Whamcloud - gitweb
LU-16915 tests: improve distro type checking
[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 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 # minutes runtime:                   5              12     8   12   15   10
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o 842"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 # Check if running on specific distros to skip certain subtests
84 if [[ "$CLIENT_OS_ID_LIKE" =~ "rhel" ]]; then
85         if (( $CLIENT_OS_VERSION_CODE == $(version_code 9.3.0) )); then
86                 # disable test_906 temporarily until rhel9.3 solves the
87                 # failure on fio io_uring I/O engine.
88                 always_except LU-17289 906
89         fi
90 fi
91
92 build_test_filter
93 FAIL_ON_ERROR=false
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 cleanup() {
98         echo -n "cln.."
99         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
100         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
101 }
102 setup() {
103         echo -n "mnt.."
104         load_modules
105         setupall || exit 10
106         echo "done"
107 }
108
109 check_swap_layouts_support()
110 {
111         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
112                 skip "Does not support layout lock."
113 }
114
115 check_swap_layout_no_dom()
116 {
117         local FOLDER=$1
118         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
119         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
120 }
121
122 check_and_setup_lustre
123 DIR=${DIR:-$MOUNT}
124 assert_DIR
125
126 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
127
128 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
129 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
130 rm -rf $DIR/[Rdfs][0-9]*
131
132 # $RUNAS_ID may get set incorrectly somewhere else
133 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
134         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
135
136 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
137
138 if [ "${ONLY}" = "MOUNT" ] ; then
139         echo "Lustre is up, please go on"
140         exit
141 fi
142
143 echo "preparing for tests involving mounts"
144 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
145 touch $EXT2_DEV
146 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
147 echo # add a newline after mke2fs.
148
149 umask 077
150
151 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
152
153 # ensure all internal functions know we want full debug
154 export PTLDEBUG=all
155 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
156
157 test_0a() {
158         touch $DIR/$tfile
159         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
160         rm $DIR/$tfile
161         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
162 }
163 run_test 0a "touch; rm ====================="
164
165 test_0b() {
166         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
167         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
168 }
169 run_test 0b "chmod 0755 $DIR ============================="
170
171 test_0c() {
172         $LCTL get_param mdc.*.import | grep "state: FULL" ||
173                 error "import not FULL"
174         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
175                 error "bad target"
176 }
177 run_test 0c "check import proc"
178
179 test_0d() { # LU-3397
180         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
181                 skip "proc exports not supported before 2.10.57"
182
183         local mgs_exp="mgs.MGS.exports"
184         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
185         local exp_client_nid
186         local exp_client_version
187         local exp_val
188         local imp_val
189         local temp_imp=$DIR/$tfile.import
190         local temp_exp=$DIR/$tfile.export
191
192         # save mgc import file to $temp_imp
193         $LCTL get_param mgc.*.import | tee $temp_imp
194         # Check if client uuid is found in MGS export
195         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
196                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
197                         $client_uuid ] &&
198                         break;
199         done
200         # save mgs export file to $temp_exp
201         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
202
203         # Compare the value of field "connect_flags"
204         imp_val=$(grep "connect_flags" $temp_imp)
205         exp_val=$(grep "connect_flags" $temp_exp)
206         [ "$exp_val" == "$imp_val" ] ||
207                 error "export flags '$exp_val' != import flags '$imp_val'"
208
209         # Compare client versions.  Only compare top-3 fields for compatibility
210         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
211         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
212         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
213         [ "$exp_val" == "$imp_val" ] ||
214                 error "exp version '$exp_client_version'($exp_val) != " \
215                         "'$(lustre_build_version client)'($imp_val)"
216 }
217 run_test 0d "check export proc ============================="
218
219 test_0e() { # LU-13417
220         (( $MDSCOUNT > 1 )) ||
221                 skip "We need at least 2 MDTs for this test"
222
223         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
224                 skip "Need server version at least 2.14.51"
225
226         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
227         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
228
229         [ $default_lmv_count -eq 1 ] ||
230                 error "$MOUNT default stripe count $default_lmv_count"
231
232         [ $default_lmv_index -eq -1 ] ||
233                 error "$MOUNT default stripe index $default_lmv_index"
234
235         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
236         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
237
238         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
239         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
240
241         [ $mdt_index1 -eq $mdt_index2 ] &&
242                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
243
244         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
245 }
246 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
247
248 test_0f() { # LU-17471
249         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
250                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
251         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
252            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
253                 skip "MDS was missing /proc/.../brw_stats value"
254
255         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
256         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
257
258         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
259 }
260 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
261
262 test_1() {
263         test_mkdir $DIR/$tdir
264         test_mkdir $DIR/$tdir/d2
265         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
266         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
267         rmdir $DIR/$tdir/d2
268         rmdir $DIR/$tdir
269         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
270 }
271 run_test 1 "mkdir; remkdir; rmdir"
272
273 test_2() {
274         test_mkdir $DIR/$tdir
275         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
276         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
277         rm -r $DIR/$tdir
278         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
279 }
280 run_test 2 "mkdir; touch; rmdir; check file"
281
282 test_3() {
283         test_mkdir $DIR/$tdir
284         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
285         touch $DIR/$tdir/$tfile
286         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
287         rm -r $DIR/$tdir
288         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
289 }
290 run_test 3 "mkdir; touch; rmdir; check dir"
291
292 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
293 test_4() {
294         test_mkdir -i 1 $DIR/$tdir
295
296         touch $DIR/$tdir/$tfile ||
297                 error "Create file under remote directory failed"
298
299         rmdir $DIR/$tdir &&
300                 error "Expect error removing in-use dir $DIR/$tdir"
301
302         test -d $DIR/$tdir || error "Remote directory disappeared"
303
304         rm -rf $DIR/$tdir || error "remove remote dir error"
305 }
306 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
307
308 test_5() {
309         test_mkdir $DIR/$tdir
310         test_mkdir $DIR/$tdir/d2
311         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
312         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
313         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
314 }
315 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
316
317 test_6a() {
318         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
319         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
320         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
321                 error "$tfile does not have perm 0666 or UID $UID"
322         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
323         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
324                 error "$tfile should be 0666 and owned by UID $UID"
325 }
326 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
327
328 test_6c() {
329         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
330
331         touch $DIR/$tfile
332         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
333         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
334                 error "$tfile should be owned by UID $RUNAS_ID"
335         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
336         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
337                 error "$tfile should be owned by UID $RUNAS_ID"
338 }
339 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
340
341 test_6e() {
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile
345         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
346         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
347                 error "$tfile should be owned by GID $UID"
348         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
349         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
350                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
351 }
352 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
353
354 test_6g() {
355         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
356
357         test_mkdir $DIR/$tdir
358         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
359         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
360         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
361         test_mkdir $DIR/$tdir/d/subdir
362         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
363                 error "$tdir/d/subdir should be GID $RUNAS_GID"
364         if [[ $MDSCOUNT -gt 1 ]]; then
365                 # check remote dir sgid inherite
366                 $LFS mkdir -i 0 $DIR/$tdir.local ||
367                         error "mkdir $tdir.local failed"
368                 chmod g+s $DIR/$tdir.local ||
369                         error "chmod $tdir.local failed"
370                 chgrp $RUNAS_GID $DIR/$tdir.local ||
371                         error "chgrp $tdir.local failed"
372                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
373                         error "mkdir $tdir.remote failed"
374                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
375                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
376                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
377                         error "$tdir.remote should be mode 02755"
378         fi
379 }
380 run_test 6g "verify new dir in sgid dir inherits group"
381
382 test_6h() { # bug 7331
383         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
384
385         touch $DIR/$tfile || error "touch failed"
386         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
387         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
388                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
389         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
390                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
391 }
392 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
393
394 test_7a() {
395         test_mkdir $DIR/$tdir
396         $MCREATE $DIR/$tdir/$tfile
397         chmod 0666 $DIR/$tdir/$tfile
398         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
399                 error "$tdir/$tfile should be mode 0666"
400 }
401 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
402
403 test_7b() {
404         if [ ! -d $DIR/$tdir ]; then
405                 test_mkdir $DIR/$tdir
406         fi
407         $MCREATE $DIR/$tdir/$tfile
408         echo -n foo > $DIR/$tdir/$tfile
409         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
410         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
411 }
412 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
413
414 test_8() {
415         test_mkdir $DIR/$tdir
416         touch $DIR/$tdir/$tfile
417         chmod 0666 $DIR/$tdir/$tfile
418         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
419                 error "$tfile mode not 0666"
420 }
421 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
422
423 test_9() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         test_mkdir $DIR/$tdir/d2/d3
427         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
428 }
429 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
430
431 test_10() {
432         test_mkdir $DIR/$tdir
433         test_mkdir $DIR/$tdir/d2
434         touch $DIR/$tdir/d2/$tfile
435         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
436                 error "$tdir/d2/$tfile not a file"
437 }
438 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
439
440 test_11() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         chmod 0666 $DIR/$tdir/d2
444         chmod 0705 $DIR/$tdir/d2
445         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
446                 error "$tdir/d2 mode not 0705"
447 }
448 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
449
450 test_12() {
451         test_mkdir $DIR/$tdir
452         touch $DIR/$tdir/$tfile
453         chmod 0666 $DIR/$tdir/$tfile
454         chmod 0654 $DIR/$tdir/$tfile
455         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
456                 error "$tdir/d2 mode not 0654"
457 }
458 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
459
460 test_13() {
461         test_mkdir $DIR/$tdir
462         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
463         >  $DIR/$tdir/$tfile
464         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
465                 error "$tdir/$tfile size not 0 after truncate"
466 }
467 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
468
469 test_14() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         rm $DIR/$tdir/$tfile
473         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
474 }
475 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
476
477 test_15() {
478         test_mkdir $DIR/$tdir
479         touch $DIR/$tdir/$tfile
480         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
481         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
482                 error "$tdir/${tfile_2} not a file after rename"
483         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
484 }
485 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
486
487 test_16() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         rm -rf $DIR/$tdir/$tfile
491         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
492 }
493 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
494
495 test_17a() {
496         test_mkdir $DIR/$tdir
497         touch $DIR/$tdir/$tfile
498         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
499         ls -l $DIR/$tdir
500         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
501                 error "$tdir/l-exist not a symlink"
502         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
503                 error "$tdir/l-exist not referencing a file"
504         rm -f $DIR/$tdir/l-exist
505         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
506 }
507 run_test 17a "symlinks: create, remove (real)"
508
509 test_17b() {
510         test_mkdir $DIR/$tdir
511         ln -s no-such-file $DIR/$tdir/l-dangle
512         ls -l $DIR/$tdir
513         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
514                 error "$tdir/l-dangle not referencing no-such-file"
515         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
516                 error "$tdir/l-dangle not referencing non-existent file"
517         rm -f $DIR/$tdir/l-dangle
518         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
519 }
520 run_test 17b "symlinks: create, remove (dangling)"
521
522 test_17c() { # bug 3440 - don't save failed open RPC for replay
523         test_mkdir $DIR/$tdir
524         ln -s foo $DIR/$tdir/$tfile
525         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
526 }
527 run_test 17c "symlinks: open dangling (should return error)"
528
529 test_17d() {
530         test_mkdir $DIR/$tdir
531         ln -s foo $DIR/$tdir/$tfile
532         touch $DIR/$tdir/$tfile || error "creating to new symlink"
533 }
534 run_test 17d "symlinks: create dangling"
535
536 test_17e() {
537         test_mkdir $DIR/$tdir
538         local foo=$DIR/$tdir/$tfile
539         ln -s $foo $foo || error "create symlink failed"
540         ls -l $foo || error "ls -l failed"
541         ls $foo && error "ls not failed" || true
542 }
543 run_test 17e "symlinks: create recursive symlink (should return error)"
544
545 test_17f() {
546         test_mkdir $DIR/$tdir
547         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
548         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
549         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
550         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
552         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
553         ls -l  $DIR/$tdir
554 }
555 run_test 17f "symlinks: long and very long symlink name"
556
557 # str_repeat(S, N) generate a string that is string S repeated N times
558 str_repeat() {
559         local s=$1
560         local n=$2
561         local ret=''
562         while [ $((n -= 1)) -ge 0 ]; do
563                 ret=$ret$s
564         done
565         echo $ret
566 }
567
568 # Long symlinks and LU-2241
569 test_17g() {
570         test_mkdir $DIR/$tdir
571         local TESTS="59 60 61 4094 4095"
572
573         # Fix for inode size boundary in 2.1.4
574         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
575                 TESTS="4094 4095"
576
577         # Patch not applied to 2.2 or 2.3 branches
578         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
579         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
580                 TESTS="4094 4095"
581
582         for i in $TESTS; do
583                 local SYMNAME=$(str_repeat 'x' $i)
584                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
585                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
586         done
587 }
588 run_test 17g "symlinks: really long symlink name and inode boundaries"
589
590 test_17h() { #bug 17378
591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
592         remote_mds_nodsh && skip "remote MDS with nodsh"
593
594         local mdt_idx
595
596         test_mkdir $DIR/$tdir
597         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
598         $LFS setstripe -c -1 $DIR/$tdir
599         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
600         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
601         touch $DIR/$tdir/$tfile || true
602 }
603 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
604
605 test_17i() { #bug 20018
606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
607         remote_mds_nodsh && skip "remote MDS with nodsh"
608
609         local foo=$DIR/$tdir/$tfile
610         local mdt_idx
611
612         test_mkdir -c1 $DIR/$tdir
613         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
614         ln -s $foo $foo || error "create symlink failed"
615 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
616         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
617         ls -l $foo && error "error not detected"
618         return 0
619 }
620 run_test 17i "don't panic on short symlink (should return error)"
621
622 test_17k() { #bug 22301
623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
624         [[ -z "$(which rsync 2>/dev/null)" ]] &&
625                 skip "no rsync command"
626         rsync --help | grep -q xattr ||
627                 skip_env "$(rsync --version | head -n1) does not support xattrs"
628         test_mkdir $DIR/$tdir
629         test_mkdir $DIR/$tdir.new
630         touch $DIR/$tdir/$tfile
631         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
632         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
633                 error "rsync failed with xattrs enabled"
634 }
635 run_test 17k "symlinks: rsync with xattrs enabled"
636
637 test_17l() { # LU-279
638         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
639                 skip "no getfattr command"
640
641         test_mkdir $DIR/$tdir
642         touch $DIR/$tdir/$tfile
643         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
644         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
645                 # -h to not follow symlinks. -m '' to list all the xattrs.
646                 # grep to remove first line: '# file: $path'.
647                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
648                 do
649                         lgetxattr_size_check $path $xattr ||
650                                 error "lgetxattr_size_check $path $xattr failed"
651                 done
652         done
653 }
654 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
655
656 # LU-1540
657 test_17m() {
658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
659         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
660         remote_mds_nodsh && skip "remote MDS with nodsh"
661         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
662         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
663                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
664
665         local short_sym="0123456789"
666         local wdir=$DIR/$tdir
667         local i
668
669         test_mkdir $wdir
670         long_sym=$short_sym
671         # create a long symlink file
672         for ((i = 0; i < 4; ++i)); do
673                 long_sym=${long_sym}${long_sym}
674         done
675
676         echo "create 512 short and long symlink files under $wdir"
677         for ((i = 0; i < 256; ++i)); do
678                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
679                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
680         done
681
682         echo "erase them"
683         rm -f $wdir/*
684         sync
685         wait_delete_completed
686
687         echo "recreate the 512 symlink files with a shorter string"
688         for ((i = 0; i < 512; ++i)); do
689                 # rewrite the symlink file with a shorter string
690                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
691                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
692         done
693
694         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
695
696         echo "stop and checking mds${mds_index}:"
697         # e2fsck should not return error
698         stop mds${mds_index}
699         local devname=$(mdsdevname $mds_index)
700         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
701         rc=$?
702
703         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
704                 error "start mds${mds_index} failed"
705         df $MOUNT > /dev/null 2>&1
706         [ $rc -eq 0 ] ||
707                 error "e2fsck detected error for short/long symlink: rc=$rc"
708         rm -f $wdir/*
709 }
710 run_test 17m "run e2fsck against MDT which contains short/long symlink"
711
712 check_fs_consistency_17n() {
713         local mdt_index
714         local rc=0
715
716         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
717         # so it only check MDT1/MDT2 instead of all of MDTs.
718         for mdt_index in 1 2; do
719                 # e2fsck should not return error
720                 stop mds${mdt_index}
721                 local devname=$(mdsdevname $mdt_index)
722                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
723                         rc=$((rc + $?))
724
725                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
726                         error "mount mds$mdt_index failed"
727                 df $MOUNT > /dev/null 2>&1
728         done
729         return $rc
730 }
731
732 test_17n() {
733         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
735         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
736         remote_mds_nodsh && skip "remote MDS with nodsh"
737         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
738         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
739                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
740
741         local i
742
743         test_mkdir $DIR/$tdir
744         for ((i=0; i<10; i++)); do
745                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
746                         error "create remote dir error $i"
747                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
748                         error "create files under remote dir failed $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after create files under remote dir"
753
754         for ((i = 0; i < 10; i++)); do
755                 rm -rf $DIR/$tdir/remote_dir_${i} ||
756                         error "destroy remote dir error $i"
757         done
758
759         check_fs_consistency_17n ||
760                 error "e2fsck report error after unlink files under remote dir"
761
762         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
763                 skip "lustre < 2.4.50 does not support migrate mv"
764
765         for ((i = 0; i < 10; i++)); do
766                 mkdir -p $DIR/$tdir/remote_dir_${i}
767                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
768                         error "create files under remote dir failed $i"
769                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
770                         error "migrate remote dir error $i"
771         done
772         check_fs_consistency_17n || error "e2fsck report error after migration"
773
774         for ((i = 0; i < 10; i++)); do
775                 rm -rf $DIR/$tdir/remote_dir_${i} ||
776                         error "destroy remote dir error $i"
777         done
778
779         check_fs_consistency_17n || error "e2fsck report error after unlink"
780 }
781 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
782
783 test_17o() {
784         remote_mds_nodsh && skip "remote MDS with nodsh"
785         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
786                 skip "Need MDS version at least 2.3.64"
787
788         local wdir=$DIR/${tdir}o
789         local mdt_index
790         local rc=0
791
792         test_mkdir $wdir
793         touch $wdir/$tfile
794         mdt_index=$($LFS getstripe -m $wdir/$tfile)
795         mdt_index=$((mdt_index + 1))
796
797         cancel_lru_locks mdc
798         #fail mds will wait the failover finish then set
799         #following fail_loc to avoid interfer the recovery process.
800         fail mds${mdt_index}
801
802         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
803         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
804         ls -l $wdir/$tfile && rc=1
805         do_facet mds${mdt_index} lctl set_param fail_loc=0
806         [[ $rc -eq 0 ]] || error "stat file should fail"
807 }
808 run_test 17o "stat file with incompat LMA feature"
809
810 test_18() {
811         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
812         ls $DIR || error "Failed to ls $DIR: $?"
813 }
814 run_test 18 "touch .../f ; ls ... =============================="
815
816 test_19a() {
817         touch $DIR/$tfile
818         ls -l $DIR
819         rm $DIR/$tfile
820         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
821 }
822 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
823
824 test_19b() {
825         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
826 }
827 run_test 19b "ls -l .../f19 (should return error) =============="
828
829 test_19c() {
830         [ $RUNAS_ID -eq $UID ] &&
831                 skip_env "RUNAS_ID = UID = $UID -- skipping"
832
833         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
834 }
835 run_test 19c "$RUNAS touch .../f19 (should return error) =="
836
837 test_19d() {
838         cat $DIR/f19 && error || true
839 }
840 run_test 19d "cat .../f19 (should return error) =============="
841
842 test_20() {
843         touch $DIR/$tfile
844         rm $DIR/$tfile
845         touch $DIR/$tfile
846         rm $DIR/$tfile
847         touch $DIR/$tfile
848         rm $DIR/$tfile
849         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
850 }
851 run_test 20 "touch .../f ; ls -l ..."
852
853 test_21() {
854         test_mkdir $DIR/$tdir
855         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
856         ln -s dangle $DIR/$tdir/link
857         echo foo >> $DIR/$tdir/link
858         cat $DIR/$tdir/dangle
859         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
860         $CHECKSTAT -f -t file $DIR/$tdir/link ||
861                 error "$tdir/link not linked to a file"
862 }
863 run_test 21 "write to dangling link"
864
865 test_22() {
866         local wdir=$DIR/$tdir
867         test_mkdir $wdir
868         chown $RUNAS_ID:$RUNAS_GID $wdir
869         (cd $wdir || error "cd $wdir failed";
870                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
871                 $RUNAS tar xf -)
872         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
873         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
874         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
875                 error "checkstat -u failed"
876 }
877 run_test 22 "unpack tar archive as non-root user"
878
879 # was test_23
880 test_23a() {
881         test_mkdir $DIR/$tdir
882         local file=$DIR/$tdir/$tfile
883
884         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
885         openfile -f O_CREAT:O_EXCL $file &&
886                 error "$file recreate succeeded" || true
887 }
888 run_test 23a "O_CREAT|O_EXCL in subdir"
889
890 test_23b() { # bug 18988
891         test_mkdir $DIR/$tdir
892         local file=$DIR/$tdir/$tfile
893
894         rm -f $file
895         echo foo > $file || error "write filed"
896         echo bar >> $file || error "append filed"
897         $CHECKSTAT -s 8 $file || error "wrong size"
898         rm $file
899 }
900 run_test 23b "O_APPEND check"
901
902 # LU-9409, size with O_APPEND and tiny writes
903 test_23c() {
904         local file=$DIR/$tfile
905
906         # single dd
907         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
908         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
909         rm -f $file
910
911         # racing tiny writes
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
914         wait
915         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
916         rm -f $file
917
918         #racing tiny & normal writes
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
920         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
921         wait
922         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
923         rm -f $file
924
925         #racing tiny & normal writes 2, ugly numbers
926         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
927         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
928         wait
929         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
930         rm -f $file
931 }
932 run_test 23c "O_APPEND size checks for tiny writes"
933
934 # LU-11069 file offset is correct after appending writes
935 test_23d() {
936         local file=$DIR/$tfile
937         local offset
938
939         echo CentaurHauls > $file
940         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
941         if ((offset != 26)); then
942                 error "wrong offset, expected 26, got '$offset'"
943         fi
944 }
945 run_test 23d "file offset is correct after appending writes"
946
947 # rename sanity
948 test_24a() {
949         echo '-- same directory rename'
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.1
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
954 }
955 run_test 24a "rename file to non-existent target"
956
957 test_24b() {
958         test_mkdir $DIR/$tdir
959         touch $DIR/$tdir/$tfile.{1,2}
960         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
961         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
962         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
963 }
964 run_test 24b "rename file to existing target"
965
966 test_24c() {
967         test_mkdir $DIR/$tdir
968         test_mkdir $DIR/$tdir/d$testnum.1
969         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
970         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
971         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
972 }
973 run_test 24c "rename directory to non-existent target"
974
975 test_24d() {
976         test_mkdir -c1 $DIR/$tdir
977         test_mkdir -c1 $DIR/$tdir/d$testnum.1
978         test_mkdir -c1 $DIR/$tdir/d$testnum.2
979         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
980         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
981         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
982 }
983 run_test 24d "rename directory to existing target"
984
985 test_24e() {
986         echo '-- cross directory renames --'
987         test_mkdir $DIR/R5a
988         test_mkdir $DIR/R5b
989         touch $DIR/R5a/f
990         mv $DIR/R5a/f $DIR/R5b/g
991         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
992         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
993 }
994 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
995
996 test_24f() {
997         test_mkdir $DIR/R6a
998         test_mkdir $DIR/R6b
999         touch $DIR/R6a/f $DIR/R6b/g
1000         mv $DIR/R6a/f $DIR/R6b/g
1001         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1002         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1003 }
1004 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1005
1006 test_24g() {
1007         test_mkdir $DIR/R7a
1008         test_mkdir $DIR/R7b
1009         test_mkdir $DIR/R7a/d
1010         mv $DIR/R7a/d $DIR/R7b/e
1011         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1012         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1013 }
1014 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1015
1016 test_24h() {
1017         test_mkdir -c1 $DIR/R8a
1018         test_mkdir -c1 $DIR/R8b
1019         test_mkdir -c1 $DIR/R8a/d
1020         test_mkdir -c1 $DIR/R8b/e
1021         mrename $DIR/R8a/d $DIR/R8b/e
1022         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1023         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1024 }
1025 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1026
1027 test_24i() {
1028         echo "-- rename error cases"
1029         test_mkdir $DIR/R9
1030         test_mkdir $DIR/R9/a
1031         touch $DIR/R9/f
1032         mrename $DIR/R9/f $DIR/R9/a
1033         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1034         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1035         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1036 }
1037 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1038
1039 test_24j() {
1040         test_mkdir $DIR/R10
1041         mrename $DIR/R10/f $DIR/R10/g
1042         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1043         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1044         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1045 }
1046 run_test 24j "source does not exist ============================"
1047
1048 test_24k() {
1049         test_mkdir $DIR/R11a
1050         test_mkdir $DIR/R11a/d
1051         touch $DIR/R11a/f
1052         mv $DIR/R11a/f $DIR/R11a/d
1053         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1054         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1055 }
1056 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1057
1058 # bug 2429 - rename foo foo foo creates invalid file
1059 test_24l() {
1060         f="$DIR/f24l"
1061         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1062 }
1063 run_test 24l "Renaming a file to itself ========================"
1064
1065 test_24m() {
1066         f="$DIR/f24m"
1067         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1068         # on ext3 this does not remove either the source or target files
1069         # though the "expected" operation would be to remove the source
1070         $CHECKSTAT -t file ${f} || error "${f} missing"
1071         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1072 }
1073 run_test 24m "Renaming a file to a hard link to itself ========="
1074
1075 test_24n() {
1076     f="$DIR/f24n"
1077     # this stats the old file after it was renamed, so it should fail
1078     touch ${f}
1079     $CHECKSTAT ${f} || error "${f} missing"
1080     mv ${f} ${f}.rename
1081     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1082     $CHECKSTAT -a ${f} || error "${f} exists"
1083 }
1084 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1085
1086 test_24o() {
1087         test_mkdir $DIR/$tdir
1088         rename_many -s random -v -n 10 $DIR/$tdir
1089 }
1090 run_test 24o "rename of files during htree split"
1091
1092 test_24p() {
1093         test_mkdir $DIR/R12a
1094         test_mkdir $DIR/R12b
1095         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1096         mrename $DIR/R12a $DIR/R12b
1097         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1098         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1099         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1100         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1101 }
1102 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1103
1104 cleanup_multiop_pause() {
1105         trap 0
1106         kill -USR1 $MULTIPID
1107 }
1108
1109 test_24q() {
1110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1111
1112         test_mkdir $DIR/R13a
1113         test_mkdir $DIR/R13b
1114         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1115         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1116         MULTIPID=$!
1117
1118         trap cleanup_multiop_pause EXIT
1119         mrename $DIR/R13a $DIR/R13b
1120         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1121         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1122         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1124         cleanup_multiop_pause
1125         wait $MULTIPID || error "multiop close failed"
1126 }
1127 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1128
1129 test_24r() { #bug 3789
1130         test_mkdir $DIR/R14a
1131         test_mkdir $DIR/R14a/b
1132         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1133         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1134         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1135 }
1136 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1137
1138 test_24s() {
1139         test_mkdir $DIR/R15a
1140         test_mkdir $DIR/R15a/b
1141         test_mkdir $DIR/R15a/b/c
1142         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1143         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1144         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1145 }
1146 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1147
1148 test_24t() {
1149         test_mkdir $DIR/R16a
1150         test_mkdir $DIR/R16a/b
1151         test_mkdir $DIR/R16a/b/c
1152         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1153         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1154         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1155 }
1156 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1157
1158 test_24u() { # bug12192
1159         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1160         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1161 }
1162 run_test 24u "create stripe file"
1163
1164 simple_cleanup_common() {
1165         local createmany=$1
1166         local rc=0
1167
1168         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1169
1170         local start=$SECONDS
1171
1172         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1173         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1174         rc=$?
1175         wait_delete_completed
1176         echo "cleanup time $((SECONDS - start))"
1177         return $rc
1178 }
1179
1180 max_pages_per_rpc() {
1181         local mdtname="$(printf "MDT%04x" ${1:-0})"
1182         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1183 }
1184
1185 test_24v() {
1186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1187
1188         local nrfiles=${COUNT:-100000}
1189         local fname="$DIR/$tdir/$tfile"
1190
1191         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1192         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1193
1194         test_mkdir "$(dirname $fname)"
1195         # assume MDT0000 has the fewest inodes
1196         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1197         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1198         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1199
1200         stack_trap "simple_cleanup_common $nrfiles"
1201
1202         createmany -m "$fname" $nrfiles
1203
1204         cancel_lru_locks mdc
1205         lctl set_param mdc.*.stats clear
1206
1207         # was previously test_24D: LU-6101
1208         # readdir() returns correct number of entries after cursor reload
1209         local num_ls=$(ls $DIR/$tdir | wc -l)
1210         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1211         local num_all=$(ls -a $DIR/$tdir | wc -l)
1212         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1213                 [ $num_all -ne $((nrfiles + 2)) ]; then
1214                         error "Expected $nrfiles files, got $num_ls " \
1215                                 "($num_uniq unique $num_all .&..)"
1216         fi
1217         # LU-5 large readdir
1218         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1219         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1220         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1221         # take into account of overhead in lu_dirpage header and end mark in
1222         # each page, plus one in rpc_num calculation.
1223         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1224         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1225         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1226         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1227         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1228         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1229         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1230         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1231                 error "large readdir doesn't take effect: " \
1232                       "$mds_readpage should be about $rpc_max"
1233 }
1234 run_test 24v "list large directory (test hash collision, b=17560)"
1235
1236 test_24w() { # bug21506
1237         SZ1=234852
1238         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1239         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1240         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1241         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1242         [[ "$SZ1" -eq "$SZ2" ]] ||
1243                 error "Error reading at the end of the file $tfile"
1244 }
1245 run_test 24w "Reading a file larger than 4Gb"
1246
1247 test_24x() {
1248         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1250         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1251                 skip "Need MDS version at least 2.7.56"
1252
1253         local MDTIDX=1
1254         local remote_dir=$DIR/$tdir/remote_dir
1255
1256         test_mkdir $DIR/$tdir
1257         $LFS mkdir -i $MDTIDX $remote_dir ||
1258                 error "create remote directory failed"
1259
1260         test_mkdir $DIR/$tdir/src_dir
1261         touch $DIR/$tdir/src_file
1262         test_mkdir $remote_dir/tgt_dir
1263         touch $remote_dir/tgt_file
1264
1265         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1266                 error "rename dir cross MDT failed!"
1267
1268         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1269                 error "rename file cross MDT failed!"
1270
1271         touch $DIR/$tdir/ln_file
1272         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1273                 error "ln file cross MDT failed"
1274
1275         rm -rf $DIR/$tdir || error "Can not delete directories"
1276 }
1277 run_test 24x "cross MDT rename/link"
1278
1279 test_24y() {
1280         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1282
1283         local remote_dir=$DIR/$tdir/remote_dir
1284         local mdtidx=1
1285
1286         test_mkdir $DIR/$tdir
1287         $LFS mkdir -i $mdtidx $remote_dir ||
1288                 error "create remote directory failed"
1289
1290         test_mkdir $remote_dir/src_dir
1291         touch $remote_dir/src_file
1292         test_mkdir $remote_dir/tgt_dir
1293         touch $remote_dir/tgt_file
1294
1295         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1296                 error "rename subdir in the same remote dir failed!"
1297
1298         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1299                 error "rename files in the same remote dir failed!"
1300
1301         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1302                 error "link files in the same remote dir failed!"
1303
1304         rm -rf $DIR/$tdir || error "Can not delete directories"
1305 }
1306 run_test 24y "rename/link on the same dir should succeed"
1307
1308 test_24z() {
1309         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1310         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1311                 skip "Need MDS version at least 2.12.51"
1312
1313         local index
1314
1315         for index in 0 1; do
1316                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1317                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1318         done
1319
1320         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1321
1322         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1323         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1324
1325         local mdts=$(comma_list $(mdts_nodes))
1326
1327         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1328         stack_trap "do_nodes $mdts $LCTL \
1329                 set_param mdt.*.enable_remote_rename=1" EXIT
1330
1331         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1332
1333         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1334         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1335 }
1336 run_test 24z "cross-MDT rename is done as cp"
1337
1338 test_24A() { # LU-3182
1339         local NFILES=5000
1340
1341         test_mkdir $DIR/$tdir
1342         stack_trap "simple_cleanup_common $NFILES"
1343         createmany -m $DIR/$tdir/$tfile $NFILES
1344         local t=$(ls $DIR/$tdir | wc -l)
1345         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1346         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1347
1348         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1349                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1350 }
1351 run_test 24A "readdir() returns correct number of entries."
1352
1353 test_24B() { # LU-4805
1354         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1355
1356         local count
1357
1358         test_mkdir $DIR/$tdir
1359         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1360                 error "create striped dir failed"
1361
1362         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1363         [ $count -eq 2 ] || error "Expected 2, got $count"
1364
1365         touch $DIR/$tdir/striped_dir/a
1366
1367         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1368         [ $count -eq 3 ] || error "Expected 3, got $count"
1369
1370         touch $DIR/$tdir/striped_dir/.f
1371
1372         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1373         [ $count -eq 4 ] || error "Expected 4, got $count"
1374
1375         rm -rf $DIR/$tdir || error "Can not delete directories"
1376 }
1377 run_test 24B "readdir for striped dir return correct number of entries"
1378
1379 test_24C() {
1380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1381
1382         mkdir $DIR/$tdir
1383         mkdir $DIR/$tdir/d0
1384         mkdir $DIR/$tdir/d1
1385
1386         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1387                 error "create striped dir failed"
1388
1389         cd $DIR/$tdir/d0/striped_dir
1390
1391         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1392         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1393         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1394
1395         [ "$d0_ino" = "$parent_ino" ] ||
1396                 error ".. wrong, expect $d0_ino, get $parent_ino"
1397
1398         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1399                 error "mv striped dir failed"
1400
1401         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1402
1403         [ "$d1_ino" = "$parent_ino" ] ||
1404                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1405 }
1406 run_test 24C "check .. in striped dir"
1407
1408 test_24E() {
1409         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1411
1412         mkdir -p $DIR/$tdir
1413         mkdir $DIR/$tdir/src_dir
1414         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1415                 error "create remote source failed"
1416
1417         touch $DIR/$tdir/src_dir/src_child/a
1418
1419         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1420                 error "create remote target dir failed"
1421
1422         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1423                 error "create remote target child failed"
1424
1425         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1426                 error "rename dir cross MDT failed!"
1427
1428         find $DIR/$tdir
1429
1430         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1431                 error "src_child still exists after rename"
1432
1433         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1434                 error "missing file(a) after rename"
1435
1436         rm -rf $DIR/$tdir || error "Can not delete directories"
1437 }
1438 run_test 24E "cross MDT rename/link"
1439
1440 test_24F () {
1441         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1442
1443         local repeats=1000
1444         [ "$SLOW" = "no" ] && repeats=100
1445
1446         mkdir -p $DIR/$tdir
1447
1448         echo "$repeats repeats"
1449         for ((i = 0; i < repeats; i++)); do
1450                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1451                 touch $DIR/$tdir/test/a || error "touch fails"
1452                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1453                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1454         done
1455
1456         true
1457 }
1458 run_test 24F "hash order vs readdir (LU-11330)"
1459
1460 test_24G () {
1461         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1462
1463         local ino1
1464         local ino2
1465
1466         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1467         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1468         touch $DIR/$tdir-0/f1 || error "touch f1"
1469         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1470         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1471         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1472         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1473         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1474 }
1475 run_test 24G "migrate symlink in rename"
1476
1477 test_24H() {
1478         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1479         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1480                 skip "MDT1 should be on another node"
1481
1482         test_mkdir -i 1 -c 1 $DIR/$tdir
1483 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1484         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1485         touch $DIR/$tdir/$tfile || error "touch failed"
1486 }
1487 run_test 24H "repeat FLD_QUERY rpc"
1488
1489 test_25a() {
1490         echo '== symlink sanity ============================================='
1491
1492         test_mkdir $DIR/d25
1493         ln -s d25 $DIR/s25
1494         touch $DIR/s25/foo ||
1495                 error "File creation in symlinked directory failed"
1496 }
1497 run_test 25a "create file in symlinked directory ==============="
1498
1499 test_25b() {
1500         [ ! -d $DIR/d25 ] && test_25a
1501         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1502 }
1503 run_test 25b "lookup file in symlinked directory ==============="
1504
1505 test_26a() {
1506         test_mkdir $DIR/d26
1507         test_mkdir $DIR/d26/d26-2
1508         ln -s d26/d26-2 $DIR/s26
1509         touch $DIR/s26/foo || error "File creation failed"
1510 }
1511 run_test 26a "multiple component symlink ======================="
1512
1513 test_26b() {
1514         test_mkdir -p $DIR/$tdir/d26-2
1515         ln -s $tdir/d26-2/foo $DIR/s26-2
1516         touch $DIR/s26-2 || error "File creation failed"
1517 }
1518 run_test 26b "multiple component symlink at end of lookup ======"
1519
1520 test_26c() {
1521         test_mkdir $DIR/d26.2
1522         touch $DIR/d26.2/foo
1523         ln -s d26.2 $DIR/s26.2-1
1524         ln -s s26.2-1 $DIR/s26.2-2
1525         ln -s s26.2-2 $DIR/s26.2-3
1526         chmod 0666 $DIR/s26.2-3/foo
1527 }
1528 run_test 26c "chain of symlinks"
1529
1530 # recursive symlinks (bug 439)
1531 test_26d() {
1532         ln -s d26-3/foo $DIR/d26-3
1533 }
1534 run_test 26d "create multiple component recursive symlink"
1535
1536 test_26e() {
1537         [ ! -h $DIR/d26-3 ] && test_26d
1538         rm $DIR/d26-3
1539 }
1540 run_test 26e "unlink multiple component recursive symlink"
1541
1542 # recursive symlinks (bug 7022)
1543 test_26f() {
1544         test_mkdir $DIR/$tdir
1545         test_mkdir $DIR/$tdir/$tfile
1546         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1547         test_mkdir -p lndir/bar1
1548         test_mkdir $DIR/$tdir/$tfile/$tfile
1549         cd $tfile                || error "cd $tfile failed"
1550         ln -s .. dotdot          || error "ln dotdot failed"
1551         ln -s dotdot/lndir lndir || error "ln lndir failed"
1552         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1553         output=`ls $tfile/$tfile/lndir/bar1`
1554         [ "$output" = bar1 ] && error "unexpected output"
1555         rm -r $tfile             || error "rm $tfile failed"
1556         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1557 }
1558 run_test 26f "rm -r of a directory which has recursive symlink"
1559
1560 test_27a() {
1561         test_mkdir $DIR/$tdir
1562         $LFS getstripe $DIR/$tdir
1563         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1564         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1565         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1566 }
1567 run_test 27a "one stripe file"
1568
1569 test_27b() {
1570         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1571
1572         test_mkdir $DIR/$tdir
1573         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1574         $LFS getstripe -c $DIR/$tdir/$tfile
1575         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1576                 error "two-stripe file doesn't have two stripes"
1577
1578         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1579 }
1580 run_test 27b "create and write to two stripe file"
1581
1582 # 27c family tests specific striping, setstripe -o
1583 test_27ca() {
1584         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1585         test_mkdir -p $DIR/$tdir
1586         local osts="1"
1587
1588         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1589         $LFS getstripe -i $DIR/$tdir/$tfile
1590         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1591                 error "stripe not on specified OST"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27ca "one stripe on specified OST"
1596
1597 test_27cb() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         test_mkdir -p $DIR/$tdir
1600         local osts="1,0"
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1602         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1603         echo "$getstripe"
1604
1605         # Strip getstripe output to a space separated list of OSTs
1606         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1607                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1608         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1609                 error "stripes not on specified OSTs"
1610
1611         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1612 }
1613 run_test 27cb "two stripes on specified OSTs"
1614
1615 test_27cc() {
1616         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1617         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1618                 skip "server does not support overstriping"
1619
1620         test_mkdir -p $DIR/$tdir
1621         local osts="0,0"
1622         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1623         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1624         echo "$getstripe"
1625
1626         # Strip getstripe output to a space separated list of OSTs
1627         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1628                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1629         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1630                 error "stripes not on specified OSTs"
1631
1632         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1633 }
1634 run_test 27cc "two stripes on the same OST"
1635
1636 test_27cd() {
1637         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1638         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1639                 skip "server does not support overstriping"
1640         test_mkdir -p $DIR/$tdir
1641         local osts="0,1,1,0"
1642         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1643         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1644         echo "$getstripe"
1645
1646         # Strip getstripe output to a space separated list of OSTs
1647         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1648                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1649         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1650                 error "stripes not on specified OSTs"
1651
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1653 }
1654 run_test 27cd "four stripes on two OSTs"
1655
1656 test_27ce() {
1657         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1658                 skip_env "too many osts, skipping"
1659         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1660                 skip "server does not support overstriping"
1661         # We do one more stripe than we have OSTs
1662         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1663                 skip_env "ea_inode feature disabled"
1664
1665         test_mkdir -p $DIR/$tdir
1666         local osts=""
1667         for i in $(seq 0 $OSTCOUNT);
1668         do
1669                 osts=$osts"0"
1670                 if [ $i -ne $OSTCOUNT ]; then
1671                         osts=$osts","
1672                 fi
1673         done
1674         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1675         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1676         echo "$getstripe"
1677
1678         # Strip getstripe output to a space separated list of OSTs
1679         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1680                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1681         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1682                 error "stripes not on specified OSTs"
1683
1684         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1685 }
1686 run_test 27ce "more stripes than OSTs with -o"
1687
1688 test_27cf() {
1689         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1690         local pid=0
1691
1692         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1693         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1694         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1695         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1696                 error "failed to set $osp_proc=0"
1697
1698         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1699         pid=$!
1700         sleep 1
1701         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1702         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1703                 error "failed to set $osp_proc=1"
1704         wait $pid
1705         [[ $pid -ne 0 ]] ||
1706                 error "should return error due to $osp_proc=0"
1707 }
1708 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1709
1710 test_27cg() {
1711         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1712                 skip "server does not support overstriping"
1713         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1714         large_xattr_enabled || skip_env "ea_inode feature disabled"
1715
1716         local osts="0"
1717
1718         for ((i=1;i<1000;i++)); do
1719                 osts+=",$((i % OSTCOUNT))"
1720         done
1721
1722         local mdts=$(comma_list $(mdts_nodes))
1723         local before=$(do_nodes $mdts \
1724                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1725                 awk '/many credits/{print $3}' |
1726                 calc_sum)
1727
1728         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1729         $LFS getstripe $DIR/$tfile | grep stripe
1730
1731         rm -f $DIR/$tfile || error "can't unlink"
1732
1733         after=$(do_nodes $mdts \
1734                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1735                 awk '/many credits/{print $3}' |
1736                 calc_sum)
1737
1738         (( before == after )) ||
1739                 error "too many credits happened: $after > $before"
1740 }
1741 run_test 27cg "1000 shouldn't cause too many credits"
1742
1743 test_27d() {
1744         test_mkdir $DIR/$tdir
1745         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1746                 error "setstripe failed"
1747         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1748         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1749 }
1750 run_test 27d "create file with default settings"
1751
1752 test_27e() {
1753         # LU-5839 adds check for existed layout before setting it
1754         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1755                 skip "Need MDS version at least 2.7.56"
1756
1757         test_mkdir $DIR/$tdir
1758         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1759         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1760         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1761 }
1762 run_test 27e "setstripe existing file (should return error)"
1763
1764 test_27f() {
1765         test_mkdir $DIR/$tdir
1766         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1767                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1768         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1769                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1770         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1771         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1772 }
1773 run_test 27f "setstripe with bad stripe size (should return error)"
1774
1775 test_27g() {
1776         test_mkdir $DIR/$tdir
1777         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1778         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1779                 error "$DIR/$tdir/$tfile has object"
1780 }
1781 run_test 27g "$LFS getstripe with no objects"
1782
1783 test_27ga() {
1784         test_mkdir $DIR/$tdir
1785         touch $DIR/$tdir/$tfile || error "touch failed"
1786         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1787         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1788         local rc=$?
1789         (( rc == 2 )) || error "getstripe did not return ENOENT"
1790
1791         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1792                         2>&1 > /dev/null)
1793         [[ $err_msg =~ "typo" ]] ||
1794                 error "expected message with correct filename, got '$err_msg'"
1795 }
1796 run_test 27ga "$LFS getstripe with missing file (should return error)"
1797
1798 test_27i() {
1799         test_mkdir $DIR/$tdir
1800         touch $DIR/$tdir/$tfile || error "touch failed"
1801         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1802                 error "missing objects"
1803 }
1804 run_test 27i "$LFS getstripe with some objects"
1805
1806 test_27j() {
1807         test_mkdir $DIR/$tdir
1808         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1809                 error "setstripe failed" || true
1810 }
1811 run_test 27j "setstripe with bad stripe offset (should return error)"
1812
1813 test_27k() { # bug 2844
1814         test_mkdir $DIR/$tdir
1815         local file=$DIR/$tdir/$tfile
1816         local ll_max_blksize=$((4 * 1024 * 1024))
1817         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1818         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1819         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1820         dd if=/dev/zero of=$file bs=4k count=1
1821         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1822         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1823 }
1824 run_test 27k "limit i_blksize for broken user apps"
1825
1826 test_27l() {
1827         mcreate $DIR/$tfile || error "creating file"
1828         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1829                 error "setstripe should have failed" || true
1830 }
1831 run_test 27l "check setstripe permissions (should return error)"
1832
1833 test_27m() {
1834         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1835
1836         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1837                 skip_env "multiple clients -- skipping"
1838
1839         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1840                    head -n1)
1841         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1842                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1843         fi
1844         stack_trap simple_cleanup_common
1845         test_mkdir $DIR/$tdir
1846         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1847         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1848                 error "dd should fill OST0"
1849         i=2
1850         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1851                 i=$((i + 1))
1852                 [ $i -gt 256 ] && break
1853         done
1854         i=$((i + 1))
1855         touch $DIR/$tdir/$tfile.$i
1856         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1857             awk '{print $1}'| grep -w "0") ] &&
1858                 error "OST0 was full but new created file still use it"
1859         i=$((i + 1))
1860         touch $DIR/$tdir/$tfile.$i
1861         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1862             awk '{print $1}'| grep -w "0") ] &&
1863                 error "OST0 was full but new created file still use it" || true
1864 }
1865 run_test 27m "create file while OST0 was full"
1866
1867 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1868 # if the OST isn't full anymore.
1869 reset_enospc() {
1870         local ostidx=${1:-""}
1871         local delay
1872         local ready
1873         local get_prealloc
1874
1875         local list=$(comma_list $(osts_nodes))
1876         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1877
1878         do_nodes $list lctl set_param fail_loc=0
1879         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1880         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1881                 awk '{print $1 * 2;exit;}')
1882         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1883                         grep -v \"^0$\""
1884         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1885 }
1886
1887 test_27n() {
1888         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1890         remote_mds_nodsh && skip "remote MDS with nodsh"
1891         remote_ost_nodsh && skip "remote OST with nodsh"
1892
1893         reset_enospc
1894         rm -f $DIR/$tdir/$tfile
1895         exhaust_precreations 0 0x80000215
1896         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1897         touch $DIR/$tdir/$tfile || error "touch failed"
1898         $LFS getstripe $DIR/$tdir/$tfile
1899         reset_enospc
1900 }
1901 run_test 27n "create file with some full OSTs"
1902
1903 test_27o() {
1904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1906         remote_mds_nodsh && skip "remote MDS with nodsh"
1907         remote_ost_nodsh && skip "remote OST with nodsh"
1908
1909         reset_enospc
1910         rm -f $DIR/$tdir/$tfile
1911         exhaust_all_precreations 0x215
1912
1913         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1914
1915         reset_enospc
1916         rm -rf $DIR/$tdir/*
1917 }
1918 run_test 27o "create file with all full OSTs (should error)"
1919
1920 function create_and_checktime() {
1921         local fname=$1
1922         local loops=$2
1923         local i
1924
1925         for ((i=0; i < $loops; i++)); do
1926                 local start=$SECONDS
1927                 multiop $fname-$i Oc
1928                 ((SECONDS-start < TIMEOUT)) ||
1929                         error "creation took " $((SECONDS-$start)) && return 1
1930         done
1931 }
1932
1933 test_27oo() {
1934         local mdts=$(comma_list $(mdts_nodes))
1935
1936         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1937                 skip "Need MDS version at least 2.13.57"
1938
1939         local f0=$DIR/${tfile}-0
1940         local f1=$DIR/${tfile}-1
1941
1942         wait_delete_completed
1943
1944         # refill precreated objects
1945         $LFS setstripe -i0 -c1 $f0
1946
1947         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1948         # force QoS allocation policy
1949         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1950         stack_trap "do_nodes $mdts $LCTL set_param \
1951                 lov.*.qos_threshold_rr=$saved" EXIT
1952         sleep_maxage
1953
1954         # one OST is unavailable, but still have few objects preallocated
1955         stop ost1
1956         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1957                 rm -rf $f1 $DIR/$tdir*" EXIT
1958
1959         for ((i=0; i < 7; i++)); do
1960                 mkdir $DIR/$tdir$i || error "can't create dir"
1961                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1962                         error "can't set striping"
1963         done
1964         for ((i=0; i < 7; i++)); do
1965                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1966         done
1967         wait
1968 }
1969 run_test 27oo "don't let few threads to reserve too many objects"
1970
1971 test_27p() {
1972         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1974         remote_mds_nodsh && skip "remote MDS with nodsh"
1975         remote_ost_nodsh && skip "remote OST with nodsh"
1976
1977         reset_enospc
1978         rm -f $DIR/$tdir/$tfile
1979         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1980
1981         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1982         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1983         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1984
1985         exhaust_precreations 0 0x80000215
1986         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1987         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1988         $LFS getstripe $DIR/$tdir/$tfile
1989
1990         reset_enospc
1991 }
1992 run_test 27p "append to a truncated file with some full OSTs"
1993
1994 test_27q() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002
2003         mkdir_on_mdt0 $DIR/$tdir
2004         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2005         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2006                 error "truncate $DIR/$tdir/$tfile failed"
2007         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2008
2009         exhaust_all_precreations 0x215
2010
2011         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2012         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2013
2014         reset_enospc
2015 }
2016 run_test 27q "append to truncated file with all OSTs full (should error)"
2017
2018 test_27r() {
2019         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2021         remote_mds_nodsh && skip "remote MDS with nodsh"
2022         remote_ost_nodsh && skip "remote OST with nodsh"
2023
2024         reset_enospc
2025         rm -f $DIR/$tdir/$tfile
2026         exhaust_precreations 0 0x80000215
2027
2028         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2029
2030         reset_enospc
2031 }
2032 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2033
2034 test_27s() { # bug 10725
2035         test_mkdir $DIR/$tdir
2036         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2037         local stripe_count=0
2038         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2039         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2040                 error "stripe width >= 2^32 succeeded" || true
2041
2042 }
2043 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2044
2045 test_27t() { # bug 10864
2046         WDIR=$(pwd)
2047         WLFS=$(which lfs)
2048         cd $DIR
2049         touch $tfile
2050         $WLFS getstripe $tfile
2051         cd $WDIR
2052 }
2053 run_test 27t "check that utils parse path correctly"
2054
2055 test_27u() { # bug 4900
2056         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2057         remote_mds_nodsh && skip "remote MDS with nodsh"
2058
2059         local index
2060         local list=$(comma_list $(mdts_nodes))
2061
2062 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2063         do_nodes $list $LCTL set_param fail_loc=0x139
2064         test_mkdir -p $DIR/$tdir
2065         stack_trap "simple_cleanup_common 1000"
2066         createmany -o $DIR/$tdir/$tfile 1000
2067         do_nodes $list $LCTL set_param fail_loc=0
2068
2069         TLOG=$TMP/$tfile.getstripe
2070         $LFS getstripe $DIR/$tdir > $TLOG
2071         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2072         [[ $OBJS -gt 0 ]] &&
2073                 error "$OBJS objects created on OST-0. See $TLOG" ||
2074                 rm -f $TLOG
2075 }
2076 run_test 27u "skip object creation on OSC w/o objects"
2077
2078 test_27v() { # bug 4900
2079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081         remote_mds_nodsh && skip "remote MDS with nodsh"
2082         remote_ost_nodsh && skip "remote OST with nodsh"
2083
2084         exhaust_all_precreations 0x215
2085         reset_enospc
2086
2087         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2088
2089         touch $DIR/$tdir/$tfile
2090         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2091         # all except ost1
2092         for (( i=1; i < OSTCOUNT; i++ )); do
2093                 do_facet ost$i lctl set_param fail_loc=0x705
2094         done
2095         local START=`date +%s`
2096         createmany -o $DIR/$tdir/$tfile 32
2097
2098         local FINISH=`date +%s`
2099         local TIMEOUT=`lctl get_param -n timeout`
2100         local PROCESS=$((FINISH - START))
2101         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2102                error "$FINISH - $START >= $TIMEOUT / 2"
2103         sleep $((TIMEOUT / 2 - PROCESS))
2104         reset_enospc
2105 }
2106 run_test 27v "skip object creation on slow OST"
2107
2108 test_27w() { # bug 10997
2109         test_mkdir $DIR/$tdir
2110         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2111         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2112                 error "stripe size $size != 65536" || true
2113         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2114                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2115 }
2116 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2117
2118 test_27wa() {
2119         [[ $OSTCOUNT -lt 2 ]] &&
2120                 skip_env "skipping multiple stripe count/offset test"
2121
2122         test_mkdir $DIR/$tdir
2123         for i in $(seq 1 $OSTCOUNT); do
2124                 offset=$((i - 1))
2125                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2126                         error "setstripe -c $i -i $offset failed"
2127                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2128                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2129                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2130                 [ $index -ne $offset ] &&
2131                         error "stripe offset $index != $offset" || true
2132         done
2133 }
2134 run_test 27wa "check $LFS setstripe -c -i options"
2135
2136 test_27x() {
2137         remote_ost_nodsh && skip "remote OST with nodsh"
2138         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2140
2141         OFFSET=$(($OSTCOUNT - 1))
2142         OSTIDX=0
2143         local OST=$(ostname_from_index $OSTIDX)
2144
2145         test_mkdir $DIR/$tdir
2146         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2147         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2148         sleep_maxage
2149         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2150         for i in $(seq 0 $OFFSET); do
2151                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2152                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2153                 error "OST0 was degraded but new created file still use it"
2154         done
2155         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2156 }
2157 run_test 27x "create files while OST0 is degraded"
2158
2159 test_27y() {
2160         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2161         remote_mds_nodsh && skip "remote MDS with nodsh"
2162         remote_ost_nodsh && skip "remote OST with nodsh"
2163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2164
2165         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2166         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2167                 osp.$mdtosc.prealloc_last_id)
2168         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2169                 osp.$mdtosc.prealloc_next_id)
2170         local fcount=$((last_id - next_id))
2171         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2172         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2173
2174         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2175                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2176         local OST_DEACTIVE_IDX=-1
2177         local OSC
2178         local OSTIDX
2179         local OST
2180
2181         for OSC in $MDS_OSCS; do
2182                 OST=$(osc_to_ost $OSC)
2183                 OSTIDX=$(index_from_ostuuid $OST)
2184                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2185                         OST_DEACTIVE_IDX=$OSTIDX
2186                 fi
2187                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2188                         echo $OSC "is Deactivated:"
2189                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2190                 fi
2191         done
2192
2193         OSTIDX=$(index_from_ostuuid $OST)
2194         test_mkdir $DIR/$tdir
2195         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2196
2197         for OSC in $MDS_OSCS; do
2198                 OST=$(osc_to_ost $OSC)
2199                 OSTIDX=$(index_from_ostuuid $OST)
2200                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2201                         echo $OST "is degraded:"
2202                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2203                                                 obdfilter.$OST.degraded=1
2204                 fi
2205         done
2206
2207         sleep_maxage
2208         createmany -o $DIR/$tdir/$tfile $fcount
2209
2210         for OSC in $MDS_OSCS; do
2211                 OST=$(osc_to_ost $OSC)
2212                 OSTIDX=$(index_from_ostuuid $OST)
2213                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2214                         echo $OST "is recovered from degraded:"
2215                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2216                                                 obdfilter.$OST.degraded=0
2217                 else
2218                         do_facet $SINGLEMDS lctl --device %$OSC activate
2219                 fi
2220         done
2221
2222         # all osp devices get activated, hence -1 stripe count restored
2223         local stripe_count=0
2224
2225         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2226         # devices get activated.
2227         sleep_maxage
2228         $LFS setstripe -c -1 $DIR/$tfile
2229         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2230         rm -f $DIR/$tfile
2231         [ $stripe_count -ne $OSTCOUNT ] &&
2232                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2233         return 0
2234 }
2235 run_test 27y "create files while OST0 is degraded and the rest inactive"
2236
2237 check_seq_oid()
2238 {
2239         log "check file $1"
2240
2241         lmm_count=$($LFS getstripe -c $1)
2242         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2243         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2244
2245         local old_ifs="$IFS"
2246         IFS=$'[:]'
2247         fid=($($LFS path2fid $1))
2248         IFS="$old_ifs"
2249
2250         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2251         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2252
2253         # compare lmm_seq and lu_fid->f_seq
2254         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2255         # compare lmm_object_id and lu_fid->oid
2256         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2257
2258         # check the trusted.fid attribute of the OST objects of the file
2259         local have_obdidx=false
2260         local stripe_nr=0
2261         $LFS getstripe $1 | while read obdidx oid hex seq; do
2262                 # skip lines up to and including "obdidx"
2263                 [ -z "$obdidx" ] && break
2264                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2265                 $have_obdidx || continue
2266
2267                 local ost=$((obdidx + 1))
2268                 local dev=$(ostdevname $ost)
2269                 local oid_hex
2270
2271                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2272
2273                 seq=$(echo $seq | sed -e "s/^0x//g")
2274                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2275                         oid_hex=$(echo $oid)
2276                 else
2277                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2278                 fi
2279                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2280
2281                 local ff=""
2282                 #
2283                 # Don't unmount/remount the OSTs if we don't need to do that.
2284                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2285                 # update too, until that use mount/ll_decode_filter_fid/mount.
2286                 # Re-enable when debugfs will understand new filter_fid.
2287                 #
2288                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2289                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2290                                 $dev 2>/dev/null" | grep "parent=")
2291                 fi
2292                 if [ -z "$ff" ]; then
2293                         stop ost$ost
2294                         mount_fstype ost$ost
2295                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2296                                 $(facet_mntpt ost$ost)/$obj_file)
2297                         unmount_fstype ost$ost
2298                         start ost$ost $dev $OST_MOUNT_OPTS
2299                         clients_up
2300                 fi
2301
2302                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2303
2304                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2305
2306                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2307                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2308                 #
2309                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2310                 #       stripe_size=1048576 component_id=1 component_start=0 \
2311                 #       component_end=33554432
2312                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2313                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2314                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2315                 local ff_pstripe
2316                 if grep -q 'stripe=' <<<$ff; then
2317                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2318                 else
2319                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2320                         # into f_ver in this case.  See comment on ff_parent.
2321                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2322                 fi
2323
2324                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2325                 [ $ff_pseq = $lmm_seq ] ||
2326                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2327                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2328                 [ $ff_poid = $lmm_oid ] ||
2329                         error "FF parent OID $ff_poid != $lmm_oid"
2330                 (($ff_pstripe == $stripe_nr)) ||
2331                         error "FF stripe $ff_pstripe != $stripe_nr"
2332
2333                 stripe_nr=$((stripe_nr + 1))
2334                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2335                         continue
2336                 if grep -q 'stripe_count=' <<<$ff; then
2337                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2338                                             -e 's/ .*//' <<<$ff)
2339                         [ $lmm_count = $ff_scnt ] ||
2340                                 error "FF stripe count $lmm_count != $ff_scnt"
2341                 fi
2342         done
2343 }
2344
2345 test_27z() {
2346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2347         remote_ost_nodsh && skip "remote OST with nodsh"
2348
2349         test_mkdir $DIR/$tdir
2350         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2351                 { error "setstripe -c -1 failed"; return 1; }
2352         # We need to send a write to every object to get parent FID info set.
2353         # This _should_ also work for setattr, but does not currently.
2354         # touch $DIR/$tdir/$tfile-1 ||
2355         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2356                 { error "dd $tfile-1 failed"; return 2; }
2357         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2358                 { error "setstripe -c -1 failed"; return 3; }
2359         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2360                 { error "dd $tfile-2 failed"; return 4; }
2361
2362         # make sure write RPCs have been sent to OSTs
2363         sync; sleep 5; sync
2364
2365         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2366         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2367 }
2368 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2369
2370 test_27A() { # b=19102
2371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2372
2373         save_layout_restore_at_exit $MOUNT
2374         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2375         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2376                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2377         local default_size=$($LFS getstripe -S $MOUNT)
2378         local default_offset=$($LFS getstripe -i $MOUNT)
2379         local dsize=$(do_facet $SINGLEMDS \
2380                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2381         [ $default_size -eq $dsize ] ||
2382                 error "stripe size $default_size != $dsize"
2383         [ $default_offset -eq -1 ] ||
2384                 error "stripe offset $default_offset != -1"
2385 }
2386 run_test 27A "check filesystem-wide default LOV EA values"
2387
2388 test_27B() { # LU-2523
2389         test_mkdir $DIR/$tdir
2390         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2391         touch $DIR/$tdir/f0
2392         # open f1 with O_LOV_DELAY_CREATE
2393         # rename f0 onto f1
2394         # call setstripe ioctl on open file descriptor for f1
2395         # close
2396         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2397                 $DIR/$tdir/f0
2398
2399         rm -f $DIR/$tdir/f1
2400         # open f1 with O_LOV_DELAY_CREATE
2401         # unlink f1
2402         # call setstripe ioctl on open file descriptor for f1
2403         # close
2404         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2405
2406         # Allow multiop to fail in imitation of NFS's busted semantics.
2407         true
2408 }
2409 run_test 27B "call setstripe on open unlinked file/rename victim"
2410
2411 # 27C family tests full striping and overstriping
2412 test_27Ca() { #LU-2871
2413         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2414
2415         declare -a ost_idx
2416         local index
2417         local found
2418         local i
2419         local j
2420
2421         test_mkdir $DIR/$tdir
2422         cd $DIR/$tdir
2423         for i in $(seq 0 $((OSTCOUNT - 1))); do
2424                 # set stripe across all OSTs starting from OST$i
2425                 $LFS setstripe -i $i -c -1 $tfile$i
2426                 # get striping information
2427                 ost_idx=($($LFS getstripe $tfile$i |
2428                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2429                 echo "OST Index: ${ost_idx[*]}"
2430
2431                 # check the layout
2432                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2433                         error "${#ost_idx[@]} != $OSTCOUNT"
2434
2435                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2436                         found=0
2437                         for j in "${ost_idx[@]}"; do
2438                                 if [ $index -eq $j ]; then
2439                                         found=1
2440                                         break
2441                                 fi
2442                         done
2443                         [ $found = 1 ] ||
2444                                 error "Can not find $index in ${ost_idx[*]}"
2445                 done
2446         done
2447 }
2448 run_test 27Ca "check full striping across all OSTs"
2449
2450 test_27Cb() {
2451         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2452                 skip "server does not support overstriping"
2453         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2454                 skip_env "too many osts, skipping"
2455
2456         test_mkdir -p $DIR/$tdir
2457         local setcount=$(($OSTCOUNT * 2))
2458         [ $setcount -lt 160 ] || large_xattr_enabled ||
2459                 skip_env "ea_inode feature disabled"
2460
2461         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2462                 error "setstripe failed"
2463
2464         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2465         [ $count -eq $setcount ] ||
2466                 error "stripe count $count, should be $setcount"
2467
2468         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2469                 error "overstriped should be set in pattern"
2470
2471         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2472                 error "dd failed"
2473 }
2474 run_test 27Cb "more stripes than OSTs with -C"
2475
2476 test_27Cc() {
2477         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2478                 skip "server does not support overstriping"
2479         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2480
2481         test_mkdir -p $DIR/$tdir
2482         local setcount=$(($OSTCOUNT - 1))
2483
2484         [ $setcount -lt 160 ] || large_xattr_enabled ||
2485                 skip_env "ea_inode feature disabled"
2486
2487         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2488                 error "setstripe failed"
2489
2490         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2491         [ $count -eq $setcount ] ||
2492                 error "stripe count $count, should be $setcount"
2493
2494         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2495                 error "overstriped should not be set in pattern"
2496
2497         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2498                 error "dd failed"
2499 }
2500 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2501
2502 test_27Cd() {
2503         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2504                 skip "server does not support overstriping"
2505         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2506         large_xattr_enabled || skip_env "ea_inode feature disabled"
2507
2508         force_new_seq_all
2509
2510         test_mkdir -p $DIR/$tdir
2511         local setcount=$LOV_MAX_STRIPE_COUNT
2512
2513         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2514                 error "setstripe failed"
2515
2516         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2517         [ $count -eq $setcount ] ||
2518                 error "stripe count $count, should be $setcount"
2519
2520         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2521                 error "overstriped should be set in pattern"
2522
2523         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2524                 error "dd failed"
2525
2526         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2527 }
2528 run_test 27Cd "test maximum stripe count"
2529
2530 test_27Ce() {
2531         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2532                 skip "server does not support overstriping"
2533         test_mkdir -p $DIR/$tdir
2534
2535         pool_add $TESTNAME || error "Pool creation failed"
2536         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2537
2538         local setcount=8
2539
2540         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2541                 error "setstripe failed"
2542
2543         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2544         [ $count -eq $setcount ] ||
2545                 error "stripe count $count, should be $setcount"
2546
2547         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2548                 error "overstriped should be set in pattern"
2549
2550         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2551                 error "dd failed"
2552
2553         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2554 }
2555 run_test 27Ce "test pool with overstriping"
2556
2557 test_27Cf() {
2558         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2559                 skip "server does not support overstriping"
2560         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2561                 skip_env "too many osts, skipping"
2562
2563         test_mkdir -p $DIR/$tdir
2564
2565         local setcount=$(($OSTCOUNT * 2))
2566         [ $setcount -lt 160 ] || large_xattr_enabled ||
2567                 skip_env "ea_inode feature disabled"
2568
2569         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2570                 error "setstripe failed"
2571
2572         echo 1 > $DIR/$tdir/$tfile
2573
2574         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2575         [ $count -eq $setcount ] ||
2576                 error "stripe count $count, should be $setcount"
2577
2578         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2579                 error "overstriped should be set in pattern"
2580
2581         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2582                 error "dd failed"
2583
2584         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2585 }
2586 run_test 27Cf "test default inheritance with overstriping"
2587
2588 test_27Cg() {
2589         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2590                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2591
2592         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2593         (( $? != 0 )) || error "must be an error for not existent OST#"
2594 }
2595 run_test 27Cg "test setstripe with wrong OST idx"
2596
2597 test_27Ci() {
2598         local tf=$DIR/$tfile
2599
2600         stack_trap "rm -f $DIR/$tfile"
2601
2602         $LFS setstripe -E1M $tf || error "create $tf failed"
2603         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2604                 error "add component failed"
2605
2606         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2607                 grep "overstriped" || {
2608                 $LFS getstripe $tf
2609                 echo "lose overstriping setting"
2610         }
2611         sc=$($LFS getstripe -I2 --stripe-count $tf)
2612         (( $sc == 100 )) || {
2613                 $LFS getstripe $tf
2614                 echo "lose overstriping setting"
2615         }
2616
2617         stack_trap "rm -f $tf"
2618         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2619         sc=$($LFS getstripe -I2 --stripe-count $tf)
2620         (( $sc == 100 )) || {
2621                 $LFS getstripe $tf
2622                 echo "lose overstriping setting after instantiation"
2623         }
2624 }
2625 run_test 27Ci "add an overstriping component"
2626
2627 test_27D() {
2628         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2629         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2630         remote_mds_nodsh && skip "remote MDS with nodsh"
2631
2632         local POOL=${POOL:-testpool}
2633         local first_ost=0
2634         local last_ost=$(($OSTCOUNT - 1))
2635         local ost_step=1
2636         local ost_list=$(seq $first_ost $ost_step $last_ost)
2637         local ost_range="$first_ost $last_ost $ost_step"
2638
2639         test_mkdir $DIR/$tdir
2640         pool_add $POOL || error "pool_add failed"
2641         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2642
2643         local skip27D
2644         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2645                 skip27D+="-s 29"
2646         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2647                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2648                         skip27D+=" -s 30,31"
2649         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2650           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2651                 skip27D+=" -s 32,33"
2652         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2653                 skip27D+=" -s 34"
2654         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2655                 error "llapi_layout_test failed"
2656
2657         destroy_test_pools || error "destroy test pools failed"
2658 }
2659 run_test 27D "validate llapi_layout API"
2660
2661 # Verify that default_easize is increased from its initial value after
2662 # accessing a widely striped file.
2663 test_27E() {
2664         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2665         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2666                 skip "client does not have LU-3338 fix"
2667
2668         # 72 bytes is the minimum space required to store striping
2669         # information for a file striped across one OST:
2670         # (sizeof(struct lov_user_md_v3) +
2671         #  sizeof(struct lov_user_ost_data_v1))
2672         local min_easize=72
2673         $LCTL set_param -n llite.*.default_easize $min_easize ||
2674                 error "lctl set_param failed"
2675         local easize=$($LCTL get_param -n llite.*.default_easize)
2676
2677         [ $easize -eq $min_easize ] ||
2678                 error "failed to set default_easize"
2679
2680         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2681                 error "setstripe failed"
2682         # In order to ensure stat() call actually talks to MDS we need to
2683         # do something drastic to this file to shake off all lock, e.g.
2684         # rename it (kills lookup lock forcing cache cleaning)
2685         mv $DIR/$tfile $DIR/${tfile}-1
2686         ls -l $DIR/${tfile}-1
2687         rm $DIR/${tfile}-1
2688
2689         easize=$($LCTL get_param -n llite.*.default_easize)
2690
2691         [ $easize -gt $min_easize ] ||
2692                 error "default_easize not updated"
2693 }
2694 run_test 27E "check that default extended attribute size properly increases"
2695
2696 test_27F() { # LU-5346/LU-7975
2697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2698         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2699         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2700                 skip "Need MDS version at least 2.8.51"
2701         remote_ost_nodsh && skip "remote OST with nodsh"
2702
2703         test_mkdir $DIR/$tdir
2704         rm -f $DIR/$tdir/f0
2705         $LFS setstripe -c 2 $DIR/$tdir
2706
2707         # stop all OSTs to reproduce situation for LU-7975 ticket
2708         for num in $(seq $OSTCOUNT); do
2709                 stop ost$num
2710         done
2711
2712         # open/create f0 with O_LOV_DELAY_CREATE
2713         # truncate f0 to a non-0 size
2714         # close
2715         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2716
2717         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2718         # open/write it again to force delayed layout creation
2719         cat /etc/hosts > $DIR/$tdir/f0 &
2720         catpid=$!
2721
2722         # restart OSTs
2723         for num in $(seq $OSTCOUNT); do
2724                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2725                         error "ost$num failed to start"
2726         done
2727
2728         wait $catpid || error "cat failed"
2729
2730         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2731         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2732                 error "wrong stripecount"
2733
2734 }
2735 run_test 27F "Client resend delayed layout creation with non-zero size"
2736
2737 test_27G() { #LU-10629
2738         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2739                 skip "Need MDS version at least 2.11.51"
2740         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2741         remote_mds_nodsh && skip "remote MDS with nodsh"
2742         local POOL=${POOL:-testpool}
2743         local ostrange="0 0 1"
2744
2745         test_mkdir $DIR/$tdir
2746         touch $DIR/$tdir/$tfile.nopool
2747         pool_add $POOL || error "pool_add failed"
2748         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2749         $LFS setstripe -p $POOL $DIR/$tdir
2750
2751         local pool=$($LFS getstripe -p $DIR/$tdir)
2752
2753         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2754         touch $DIR/$tdir/$tfile.default
2755         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2756         $LFS find $DIR/$tdir -type f --pool $POOL
2757         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2758         [[ "$found" == "2" ]] ||
2759                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2760
2761         $LFS setstripe -d $DIR/$tdir
2762
2763         pool=$($LFS getstripe -p -d $DIR/$tdir)
2764
2765         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2766 }
2767 run_test 27G "Clear OST pool from stripe"
2768
2769 test_27H() {
2770         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2771                 skip "Need MDS version newer than 2.11.54"
2772         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2773         test_mkdir $DIR/$tdir
2774         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2775         touch $DIR/$tdir/$tfile
2776         $LFS getstripe -c $DIR/$tdir/$tfile
2777         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2778                 error "two-stripe file doesn't have two stripes"
2779
2780         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2781         $LFS getstripe -y $DIR/$tdir/$tfile
2782         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2783              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2784                 error "expected l_ost_idx: [02]$ not matched"
2785
2786         # make sure ost list has been cleared
2787         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2788         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2789                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2790         touch $DIR/$tdir/f3
2791         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2792 }
2793 run_test 27H "Set specific OSTs stripe"
2794
2795 test_27I() {
2796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2798         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2799                 skip "Need MDS version newer than 2.12.52"
2800         local pool=$TESTNAME
2801         local ostrange="1 1 1"
2802
2803         save_layout_restore_at_exit $MOUNT
2804         $LFS setstripe -c 2 -i 0 $MOUNT
2805         pool_add $pool || error "pool_add failed"
2806         pool_add_targets $pool $ostrange ||
2807                 error "pool_add_targets failed"
2808         test_mkdir $DIR/$tdir
2809         $LFS setstripe -p $pool $DIR/$tdir
2810         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2811         $LFS getstripe $DIR/$tdir/$tfile
2812 }
2813 run_test 27I "check that root dir striping does not break parent dir one"
2814
2815 test_27J() {
2816         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2817                 skip "Need MDS version newer than 2.12.51"
2818
2819         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2820         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2821         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2822            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2823                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2824
2825         test_mkdir $DIR/$tdir
2826         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2827         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2828
2829         # create foreign file (raw way)
2830         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2831                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2832
2833         ! $LFS setstripe --foreign --flags foo \
2834                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2835                         error "creating $tfile with '--flags foo' should fail"
2836
2837         ! $LFS setstripe --foreign --flags 0xffffffff \
2838                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2839                         error "creating $tfile w/ 0xffffffff flags should fail"
2840
2841         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2842                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2843
2844         # verify foreign file (raw way)
2845         parse_foreign_file -f $DIR/$tdir/$tfile |
2846                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2847                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2848         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2849                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2850         parse_foreign_file -f $DIR/$tdir/$tfile |
2851                 grep "lov_foreign_size: 73" ||
2852                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2853         parse_foreign_file -f $DIR/$tdir/$tfile |
2854                 grep "lov_foreign_type: 1" ||
2855                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2856         parse_foreign_file -f $DIR/$tdir/$tfile |
2857                 grep "lov_foreign_flags: 0x0000DA08" ||
2858                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2859         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2860                 grep "lov_foreign_value: 0x" |
2861                 sed -e 's/lov_foreign_value: 0x//')
2862         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2863         [[ $lov = ${lov2// /} ]] ||
2864                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2865
2866         # create foreign file (lfs + API)
2867         $LFS setstripe --foreign=none --flags 0xda08 \
2868                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2869                 error "$DIR/$tdir/${tfile}2: create failed"
2870
2871         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2872                 grep "lfm_magic:.*0x0BD70BD0" ||
2873                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2874         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2875         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2876                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2877         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2878                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2879         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2880                 grep "lfm_flags:.*0x0000DA08" ||
2881                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2882         $LFS getstripe $DIR/$tdir/${tfile}2 |
2883                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2884                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2885
2886         # modify striping should fail
2887         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2888                 error "$DIR/$tdir/$tfile: setstripe should fail"
2889         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2890                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2891
2892         # R/W should fail
2893         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2894         cat $DIR/$tdir/${tfile}2 &&
2895                 error "$DIR/$tdir/${tfile}2: read should fail"
2896         cat /etc/passwd > $DIR/$tdir/$tfile &&
2897                 error "$DIR/$tdir/$tfile: write should fail"
2898         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2899                 error "$DIR/$tdir/${tfile}2: write should fail"
2900
2901         # chmod should work
2902         chmod 222 $DIR/$tdir/$tfile ||
2903                 error "$DIR/$tdir/$tfile: chmod failed"
2904         chmod 222 $DIR/$tdir/${tfile}2 ||
2905                 error "$DIR/$tdir/${tfile}2: chmod failed"
2906
2907         # chown should work
2908         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2909                 error "$DIR/$tdir/$tfile: chown failed"
2910         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2911                 error "$DIR/$tdir/${tfile}2: chown failed"
2912
2913         # rename should work
2914         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2915                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2916         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2917                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2918
2919         #remove foreign file
2920         rm $DIR/$tdir/${tfile}.new ||
2921                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2922         rm $DIR/$tdir/${tfile}2.new ||
2923                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2924 }
2925 run_test 27J "basic ops on file with foreign LOV"
2926
2927 test_27K() {
2928         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2929                 skip "Need MDS version newer than 2.12.49"
2930
2931         test_mkdir $DIR/$tdir
2932         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2933         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2934
2935         # create foreign dir (raw way)
2936         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2937                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2938
2939         ! $LFS setdirstripe --foreign --flags foo \
2940                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2941                         error "creating $tdir with '--flags foo' should fail"
2942
2943         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2944                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2945                         error "creating $tdir w/ 0xffffffff flags should fail"
2946
2947         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2948                 error "create_foreign_dir FAILED"
2949
2950         # verify foreign dir (raw way)
2951         parse_foreign_dir -d $DIR/$tdir/$tdir |
2952                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2953                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2954         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2955                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2956         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2957                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2958         parse_foreign_dir -d $DIR/$tdir/$tdir |
2959                 grep "lmv_foreign_flags: 55813$" ||
2960                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2961         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2962                 grep "lmv_foreign_value: 0x" |
2963                 sed 's/lmv_foreign_value: 0x//')
2964         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2965                 sed 's/ //g')
2966         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2967
2968         # create foreign dir (lfs + API)
2969         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2970                 $DIR/$tdir/${tdir}2 ||
2971                 error "$DIR/$tdir/${tdir}2: create failed"
2972
2973         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2974
2975         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2976                 grep "lfm_magic:.*0x0CD50CD0" ||
2977                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2978         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2979         # - sizeof(lfm_type) - sizeof(lfm_flags)
2980         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2981                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2982         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2983                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2984         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2985                 grep "lfm_flags:.*0x0000DA05" ||
2986                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2987         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2988                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2989                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2990
2991         # file create in dir should fail
2992         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2993         touch $DIR/$tdir/${tdir}2/$tfile &&
2994                 error "$DIR/${tdir}2: file create should fail"
2995
2996         # chmod should work
2997         chmod 777 $DIR/$tdir/$tdir ||
2998                 error "$DIR/$tdir: chmod failed"
2999         chmod 777 $DIR/$tdir/${tdir}2 ||
3000                 error "$DIR/${tdir}2: chmod failed"
3001
3002         # chown should work
3003         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3004                 error "$DIR/$tdir: chown failed"
3005         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3006                 error "$DIR/${tdir}2: chown failed"
3007
3008         # rename should work
3009         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3010                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3011         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3012                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3013
3014         #remove foreign dir
3015         rmdir $DIR/$tdir/${tdir}.new ||
3016                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3017         rmdir $DIR/$tdir/${tdir}2.new ||
3018                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3019 }
3020 run_test 27K "basic ops on dir with foreign LMV"
3021
3022 test_27L() {
3023         remote_mds_nodsh && skip "remote MDS with nodsh"
3024
3025         local POOL=${POOL:-$TESTNAME}
3026
3027         pool_add $POOL || error "pool_add failed"
3028
3029         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3030                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3031                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3032 }
3033 run_test 27L "lfs pool_list gives correct pool name"
3034
3035 test_27M() {
3036         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3037                 skip "Need MDS version >= than 2.12.57"
3038         remote_mds_nodsh && skip "remote MDS with nodsh"
3039         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3040
3041         # Set default striping on directory
3042         local setcount=4
3043         local stripe_opt
3044         local mdts=$(comma_list $(mdts_nodes))
3045
3046         # if we run against a 2.12 server which lacks overstring support
3047         # then the connect_flag will not report overstriping, even if client
3048         # is 2.14+
3049         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3050                 stripe_opt="-C $setcount"
3051         elif (( $OSTCOUNT >= $setcount )); then
3052                 stripe_opt="-c $setcount"
3053         else
3054                 skip "server does not support overstriping"
3055         fi
3056
3057         test_mkdir $DIR/$tdir
3058
3059         # Validate existing append_* params and ensure restore
3060         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3061         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3062         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3063
3064         # Validate append_pool name length
3065         (( $MDS1_VERSION >= $(version_code 2.15.61) )) &&
3066                 do_nodes $mdts $LCTL \
3067                         set_param mdd.*.append_pool="LOV_MAXPOOLNAME*" &&
3068                         error "Wrong pool name length should report error"
3069
3070         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3071         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3072         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3073
3074         $LFS setstripe $stripe_opt $DIR/$tdir
3075
3076         echo 1 > $DIR/$tdir/${tfile}.1
3077         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3078         (( $count == $setcount )) ||
3079                 error "(1) stripe count $count, should be $setcount"
3080
3081         local appendcount=$orig_count
3082         echo 1 >> $DIR/$tdir/${tfile}.2_append
3083         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3084         (( $count == $appendcount )) ||
3085                 error "(2)stripe count $count, should be $appendcount for append"
3086
3087         # Disable O_APPEND striping, verify it works
3088         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3089
3090         # Should now get the default striping, which is 4
3091         setcount=4
3092         echo 1 >> $DIR/$tdir/${tfile}.3_append
3093         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3094         (( $count == $setcount )) ||
3095                 error "(3) stripe count $count, should be $setcount"
3096
3097         # Try changing the stripe count for append files
3098         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3099
3100         # Append striping is now 2 (directory default is still 4)
3101         appendcount=2
3102         echo 1 >> $DIR/$tdir/${tfile}.4_append
3103         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3104         (( $count == $appendcount )) ||
3105                 error "(4) stripe count $count, should be $appendcount for append"
3106
3107         # Test append stripe count of -1
3108         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3109         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3110                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3111                 touch $DIR/$tdir/$tfile.specific.{1..128}
3112         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3113
3114         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3115         appendcount=$OSTCOUNT
3116         echo 1 >> $DIR/$tdir/${tfile}.5
3117         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3118         (( $count == $appendcount )) ||
3119                 error "(5) stripe count $count, should be $appendcount for append"
3120
3121         # Set append striping back to default of 1
3122         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3123
3124         # Try a new default striping, PFL + DOM
3125         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3126
3127         # Create normal DOM file, DOM returns stripe count == 0
3128         setcount=0
3129         touch $DIR/$tdir/${tfile}.6
3130         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3131         (( $count == $setcount )) ||
3132                 error "(6) stripe count $count, should be $setcount"
3133
3134         # Show
3135         appendcount=1
3136         echo 1 >> $DIR/$tdir/${tfile}.7_append
3137         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3138         (( $count == $appendcount )) ||
3139                 error "(7) stripe count $count, should be $appendcount for append"
3140
3141         # Clean up DOM layout
3142         $LFS setstripe -d $DIR/$tdir
3143
3144         save_layout_restore_at_exit $MOUNT
3145         # Now test that append striping works when layout is from root
3146         $LFS setstripe -c 2 $MOUNT
3147         # Make a special directory for this
3148         mkdir $DIR/${tdir}/${tdir}.2
3149
3150         # Verify for normal file
3151         setcount=2
3152         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3153         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3154         (( $count == $setcount )) ||
3155                 error "(8) stripe count $count, should be $setcount"
3156
3157         appendcount=1
3158         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3159         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3160         (( $count == $appendcount )) ||
3161                 error "(9) stripe count $count, should be $appendcount for append"
3162
3163         # Now test O_APPEND striping with pools
3164         pool_add $TESTNAME || error "pool creation failed"
3165         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3166         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3167
3168         echo 1 >> $DIR/$tdir/${tfile}.10_append
3169
3170         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3171         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3172
3173         # Check that count is still correct
3174         appendcount=1
3175         echo 1 >> $DIR/$tdir/${tfile}.11_append
3176         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3177         (( $count == $appendcount )) ||
3178                 error "(11) stripe count $count, should be $appendcount for append"
3179
3180         # Disable O_APPEND stripe count, verify pool works separately
3181         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3182
3183         echo 1 >> $DIR/$tdir/${tfile}.12_append
3184
3185         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3186         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3187
3188         # Remove pool setting, verify it's not applied
3189         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3190
3191         echo 1 >> $DIR/$tdir/${tfile}.13_append
3192
3193         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3194         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3195 }
3196 run_test 27M "test O_APPEND striping"
3197
3198 test_27N() {
3199         combined_mgs_mds && skip "needs separate MGS/MDT"
3200
3201         pool_add $TESTNAME || error "pool_add failed"
3202         do_facet mgs "$LCTL pool_list $FSNAME" |
3203                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3204                 error "lctl pool_list on MGS failed"
3205 }
3206 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3207
3208 clean_foreign_symlink() {
3209         trap 0
3210         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3211         for i in $DIR/$tdir/* ; do
3212                 $LFS unlink_foreign $i || true
3213         done
3214 }
3215
3216 test_27O() {
3217         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3218                 skip "Need MDS version newer than 2.12.51"
3219
3220         test_mkdir $DIR/$tdir
3221         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3222         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3223
3224         trap clean_foreign_symlink EXIT
3225
3226         # enable foreign_symlink behaviour
3227         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3228
3229         # foreign symlink LOV format is a partial path by default
3230
3231         # create foreign file (lfs + API)
3232         $LFS setstripe --foreign=symlink --flags 0xda05 \
3233                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3234                 error "$DIR/$tdir/${tfile}: create failed"
3235
3236         $LFS getstripe -v $DIR/$tdir/${tfile} |
3237                 grep "lfm_magic:.*0x0BD70BD0" ||
3238                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3239         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3240                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3241         $LFS getstripe -v $DIR/$tdir/${tfile} |
3242                 grep "lfm_flags:.*0x0000DA05" ||
3243                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3244         $LFS getstripe $DIR/$tdir/${tfile} |
3245                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3246                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3247
3248         # modify striping should fail
3249         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3250                 error "$DIR/$tdir/$tfile: setstripe should fail"
3251
3252         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3253         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3254         cat /etc/passwd > $DIR/$tdir/$tfile &&
3255                 error "$DIR/$tdir/$tfile: write should fail"
3256
3257         # rename should succeed
3258         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3259                 error "$DIR/$tdir/$tfile: rename has failed"
3260
3261         #remove foreign_symlink file should fail
3262         rm $DIR/$tdir/${tfile}.new &&
3263                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3264
3265         #test fake symlink
3266         mkdir /tmp/${uuid1} ||
3267                 error "/tmp/${uuid1}: mkdir has failed"
3268         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3269                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3270         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3271         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3272                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3273         #read should succeed now
3274         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3275                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3276         #write should succeed now
3277         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3278                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3279         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3280                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3281         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3282                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3283
3284         #check that getstripe still works
3285         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3286                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3287
3288         # chmod should still succeed
3289         chmod 644 $DIR/$tdir/${tfile}.new ||
3290                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3291
3292         # chown should still succeed
3293         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3294                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3295
3296         # rename should still succeed
3297         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3298                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3299
3300         #remove foreign_symlink file should still fail
3301         rm $DIR/$tdir/${tfile} &&
3302                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3303
3304         #use special ioctl() to unlink foreign_symlink file
3305         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3306                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3307
3308 }
3309 run_test 27O "basic ops on foreign file of symlink type"
3310
3311 test_27P() {
3312         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3313                 skip "Need MDS version newer than 2.12.49"
3314
3315         test_mkdir $DIR/$tdir
3316         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3317         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3318
3319         trap clean_foreign_symlink EXIT
3320
3321         # enable foreign_symlink behaviour
3322         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3323
3324         # foreign symlink LMV format is a partial path by default
3325
3326         # create foreign dir (lfs + API)
3327         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3328                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3329                 error "$DIR/$tdir/${tdir}: create failed"
3330
3331         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3332
3333         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3334                 grep "lfm_magic:.*0x0CD50CD0" ||
3335                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3336         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3337                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3338         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3339                 grep "lfm_flags:.*0x0000DA05" ||
3340                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3341         $LFS getdirstripe $DIR/$tdir/${tdir} |
3342                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3343                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3344
3345         # file create in dir should fail
3346         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3347         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3348
3349         # rename should succeed
3350         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3351                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3352
3353         #remove foreign_symlink dir should fail
3354         rmdir $DIR/$tdir/${tdir}.new &&
3355                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3356
3357         #test fake symlink
3358         mkdir -p /tmp/${uuid1}/${uuid2} ||
3359                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3360         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3361                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3362         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3363         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3364                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3365         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3366                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3367
3368         #check that getstripe fails now that foreign_symlink enabled
3369         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3370                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3371
3372         # file create in dir should work now
3373         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3374                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3375         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3376                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3377         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3378                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3379
3380         # chmod should still succeed
3381         chmod 755 $DIR/$tdir/${tdir}.new ||
3382                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3383
3384         # chown should still succeed
3385         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3386                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3387
3388         # rename should still succeed
3389         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3390                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3391
3392         #remove foreign_symlink dir should still fail
3393         rmdir $DIR/$tdir/${tdir} &&
3394                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3395
3396         #use special ioctl() to unlink foreign_symlink file
3397         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3398                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3399
3400         #created file should still exist
3401         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3402                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3403         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3404                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3405 }
3406 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3407
3408 test_27Q() {
3409         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3410         stack_trap "rm -f $TMP/$tfile*"
3411
3412         test_mkdir $DIR/$tdir-1
3413         test_mkdir $DIR/$tdir-2
3414
3415         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3416         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3417
3418         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3419         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3420
3421         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3422         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3423
3424         # Create some bad symlinks and ensure that we don't loop
3425         # forever or something. These should return ELOOP (40) and
3426         # ENOENT (2) but I don't want to test for that because there's
3427         # always some weirdo architecture that needs to ruin
3428         # everything by defining these error numbers differently.
3429
3430         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3431         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3432
3433         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3434         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3435
3436         return 0
3437 }
3438 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3439
3440 test_27R() {
3441         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3442                 skip "need MDS 2.14.55 or later"
3443         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3444
3445         local testdir="$DIR/$tdir"
3446         test_mkdir -p $testdir
3447         stack_trap "rm -rf $testdir"
3448         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3449
3450         local f1="$testdir/f1"
3451         touch $f1 || error "failed to touch $f1"
3452         local count=$($LFS getstripe -c $f1)
3453         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3454
3455         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3456         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3457
3458         local maxcount=$(($OSTCOUNT - 1))
3459         local mdts=$(comma_list $(mdts_nodes))
3460         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3461         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3462
3463         local f2="$testdir/f2"
3464         touch $f2 || error "failed to touch $f2"
3465         local count=$($LFS getstripe -c $f2)
3466         (( $count == $maxcount )) || error "wrong stripe count"
3467 }
3468 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3469
3470 test_27T() {
3471         [ $(facet_host client) == $(facet_host ost1) ] &&
3472                 skip "need ost1 and client on different nodes"
3473
3474 #define OBD_FAIL_OSC_NO_GRANT            0x411
3475         $LCTL set_param fail_loc=0x20000411 fail_val=1
3476 #define OBD_FAIL_OST_ENOSPC              0x215
3477         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3478         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3479         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3480                 error "multiop failed"
3481 }
3482 run_test 27T "no eio on close on partial write due to enosp"
3483
3484 test_27U() {
3485         local dir=$DIR/$tdir
3486         local file=$dir/$tfile
3487         local append_pool=${TESTNAME}-append
3488         local normal_pool=${TESTNAME}-normal
3489         local pool
3490         local stripe_count
3491         local stripe_count2
3492         local mdts=$(comma_list $(mdts_nodes))
3493
3494         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3495                 skip "Need MDS version at least 2.15.51 for append pool feature"
3496
3497         # Validate existing append_* params and ensure restore
3498         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3499         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3500         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3501
3502         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3503         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3504         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3505
3506         pool_add $append_pool || error "pool creation failed"
3507         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3508
3509         pool_add $normal_pool || error "pool creation failed"
3510         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3511
3512         test_mkdir $dir
3513         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3514
3515         echo XXX >> $file.1
3516         $LFS getstripe $file.1
3517
3518         pool=$($LFS getstripe -p $file.1)
3519         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3520
3521         stripe_count2=$($LFS getstripe -c $file.1)
3522         ((stripe_count2 == stripe_count)) ||
3523                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3524
3525         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3526
3527         echo XXX >> $file.2
3528         $LFS getstripe $file.2
3529
3530         pool=$($LFS getstripe -p $file.2)
3531         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3532
3533         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3534
3535         echo XXX >> $file.3
3536         $LFS getstripe $file.3
3537
3538         stripe_count2=$($LFS getstripe -c $file.3)
3539         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3540 }
3541 run_test 27U "append pool and stripe count work with composite default layout"
3542
3543 test_27V() {
3544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3545         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3546
3547         local dir=$DIR/$tdir
3548         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3549         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3550         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3551         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3552         local pid
3553
3554         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3555
3556         do_facet mds1 $LCTL set_param $lod_param=0
3557         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3558
3559         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3560         stack_trap "rm -rf $dir"
3561
3562         # exercise race in LU-16981 with deactivating OST while creating a file
3563         (
3564                 while true; do
3565                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3566                         sleep 0.1
3567                         do_facet mds1 \
3568                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3569                 done
3570         ) &
3571
3572         pid=$!
3573         stack_trap "kill -9 $pid"
3574
3575         # errors here are OK so ignore them (just don't want to crash)
3576         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3577
3578         return 0
3579 }
3580 run_test 27V "creating widely striped file races with deactivating OST"
3581
3582 # createtest also checks that device nodes are created and
3583 # then visible correctly (#2091)
3584 test_28() { # bug 2091
3585         test_mkdir $DIR/d28
3586         $CREATETEST $DIR/d28/ct || error "createtest failed"
3587 }
3588 run_test 28 "create/mknod/mkdir with bad file types ============"
3589
3590 test_29() {
3591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3592
3593         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3594                 disable_opencache
3595                 stack_trap "restore_opencache"
3596         }
3597
3598         sync; sleep 1; sync # flush out any dirty pages from previous tests
3599         cancel_lru_locks
3600         test_mkdir $DIR/d29
3601         touch $DIR/d29/foo
3602         log 'first d29'
3603         ls -l $DIR/d29
3604
3605         local locks_orig=$(total_used_locks mdc)
3606         (( $locks_orig != 0 )) || error "No mdc lock count"
3607
3608         local locks_unused_orig=$(total_unused_locks mdc)
3609
3610         log 'second d29'
3611         ls -l $DIR/d29
3612         log 'done'
3613
3614         local locks_current=$(total_used_locks mdc)
3615
3616         local locks_unused_current=$(total_unused_locks mdc)
3617
3618         if (( $locks_current > $locks_orig )); then
3619                 $LCTL set_param -n ldlm.dump_namespaces ""
3620                 error "CURRENT: $locks_current > $locks_orig"
3621         fi
3622         if (( $locks_unused_current > $locks_unused_orig )); then
3623                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3624         fi
3625 }
3626 run_test 29 "IT_GETATTR regression  ============================"
3627
3628 test_30a() { # was test_30
3629         cp $(which ls) $DIR || cp /bin/ls $DIR
3630         $DIR/ls / || error "Can't execute binary from lustre"
3631         rm $DIR/ls
3632 }
3633 run_test 30a "execute binary from Lustre (execve) =============="
3634
3635 test_30b() {
3636         cp `which ls` $DIR || cp /bin/ls $DIR
3637         chmod go+rx $DIR/ls
3638         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3639         rm $DIR/ls
3640 }
3641 run_test 30b "execute binary from Lustre as non-root ==========="
3642
3643 test_30c() { # b=22376
3644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3645
3646         cp $(which ls) $DIR || cp /bin/ls $DIR
3647         chmod a-rw $DIR/ls
3648         cancel_lru_locks mdc
3649         cancel_lru_locks osc
3650         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3651         rm -f $DIR/ls
3652 }
3653 run_test 30c "execute binary from Lustre without read perms ===="
3654
3655 test_30d() {
3656         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3657
3658         for i in {1..10}; do
3659                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3660                 local PID=$!
3661                 sleep 1
3662                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3663                 wait $PID || error "executing dd from Lustre failed"
3664                 rm -f $DIR/$tfile
3665         done
3666
3667         rm -f $DIR/dd
3668 }
3669 run_test 30d "execute binary from Lustre while clear locks"
3670
3671 test_31a() {
3672         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3673         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3674 }
3675 run_test 31a "open-unlink file =================================="
3676
3677 test_31b() {
3678         touch $DIR/f31 || error "touch $DIR/f31 failed"
3679         ln $DIR/f31 $DIR/f31b || error "ln failed"
3680         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3681         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3682 }
3683 run_test 31b "unlink file with multiple links while open ======="
3684
3685 test_31c() {
3686         touch $DIR/f31 || error "touch $DIR/f31 failed"
3687         ln $DIR/f31 $DIR/f31c || error "ln failed"
3688         multiop_bg_pause $DIR/f31 O_uc ||
3689                 error "multiop_bg_pause for $DIR/f31 failed"
3690         MULTIPID=$!
3691         $MULTIOP $DIR/f31c Ouc
3692         kill -USR1 $MULTIPID
3693         wait $MULTIPID
3694 }
3695 run_test 31c "open-unlink file with multiple links ============="
3696
3697 test_31d() {
3698         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3699         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3700 }
3701 run_test 31d "remove of open directory ========================="
3702
3703 test_31e() { # bug 2904
3704         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3705 }
3706 run_test 31e "remove of open non-empty directory ==============="
3707
3708 test_31f() { # bug 4554
3709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3710
3711         set -vx
3712         test_mkdir $DIR/d31f
3713         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3714         cp /etc/hosts $DIR/d31f
3715         ls -l $DIR/d31f
3716         $LFS getstripe $DIR/d31f/hosts
3717         multiop_bg_pause $DIR/d31f D_c || return 1
3718         MULTIPID=$!
3719
3720         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3721         test_mkdir $DIR/d31f
3722         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3723         cp /etc/hosts $DIR/d31f
3724         ls -l $DIR/d31f
3725         $LFS getstripe $DIR/d31f/hosts
3726         multiop_bg_pause $DIR/d31f D_c || return 1
3727         MULTIPID2=$!
3728
3729         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3730         wait $MULTIPID || error "first opendir $MULTIPID failed"
3731
3732         sleep 6
3733
3734         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3735         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3736         set +vx
3737 }
3738 run_test 31f "remove of open directory with open-unlink file ==="
3739
3740 test_31g() {
3741         echo "-- cross directory link --"
3742         test_mkdir -c1 $DIR/${tdir}ga
3743         test_mkdir -c1 $DIR/${tdir}gb
3744         touch $DIR/${tdir}ga/f
3745         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3746         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3747         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3748         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3749         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3750 }
3751 run_test 31g "cross directory link==============="
3752
3753 test_31h() {
3754         echo "-- cross directory link --"
3755         test_mkdir -c1 $DIR/${tdir}
3756         test_mkdir -c1 $DIR/${tdir}/dir
3757         touch $DIR/${tdir}/f
3758         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3759         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3760         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3761         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3762         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3763 }
3764 run_test 31h "cross directory link under child==============="
3765
3766 test_31i() {
3767         echo "-- cross directory link --"
3768         test_mkdir -c1 $DIR/$tdir
3769         test_mkdir -c1 $DIR/$tdir/dir
3770         touch $DIR/$tdir/dir/f
3771         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3772         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3773         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3774         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3775         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3776 }
3777 run_test 31i "cross directory link under parent==============="
3778
3779 test_31j() {
3780         test_mkdir -c1 -p $DIR/$tdir
3781         test_mkdir -c1 -p $DIR/$tdir/dir1
3782         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3783         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3784         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3785         return 0
3786 }
3787 run_test 31j "link for directory"
3788
3789 test_31k() {
3790         test_mkdir -c1 -p $DIR/$tdir
3791         touch $DIR/$tdir/s
3792         touch $DIR/$tdir/exist
3793         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3794         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3795         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3796         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3797         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3798         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3799         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3800         return 0
3801 }
3802 run_test 31k "link to file: the same, non-existing, dir"
3803
3804 test_31l() {
3805         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3806
3807         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3808         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3809                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3810
3811         touch $DIR/$tfile || error "create failed"
3812         mkdir $DIR/$tdir || error "mkdir failed"
3813         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3814 }
3815 run_test 31l "link to file: target dir has trailing slash"
3816
3817 test_31m() {
3818         mkdir $DIR/d31m
3819         touch $DIR/d31m/s
3820         mkdir $DIR/d31m2
3821         touch $DIR/d31m2/exist
3822         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3823         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3824         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3825         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3826         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3827         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3828         return 0
3829 }
3830 run_test 31m "link to file: the same, non-existing, dir"
3831
3832 test_31n() {
3833         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3834         nlink=$(stat --format=%h $DIR/$tfile)
3835         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3836         local fd=$(free_fd)
3837         local cmd="exec $fd<$DIR/$tfile"
3838         eval $cmd
3839         cmd="exec $fd<&-"
3840         trap "eval $cmd" EXIT
3841         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3842         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3843         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3844         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3845         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3846         eval $cmd
3847 }
3848 run_test 31n "check link count of unlinked file"
3849
3850 link_one() {
3851         local tempfile=$(mktemp $1_XXXXXX)
3852         link $tempfile $1 2> /dev/null &&
3853                 echo "$BASHPID: link $tempfile to $1 succeeded"
3854         unlink $tempfile
3855 }
3856
3857 test_31o() { # LU-2901
3858         test_mkdir $DIR/$tdir
3859         for LOOP in $(seq 100); do
3860                 rm -f $DIR/$tdir/$tfile*
3861                 for THREAD in $(seq 8); do
3862                         link_one $DIR/$tdir/$tfile.$LOOP &
3863                 done
3864                 wait
3865                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3866                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3867                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3868                         break || true
3869         done
3870 }
3871 run_test 31o "duplicate hard links with same filename"
3872
3873 test_31p() {
3874         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3875
3876         test_mkdir $DIR/$tdir
3877         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3878         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3879
3880         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3881                 error "open unlink test1 failed"
3882         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3883                 error "open unlink test2 failed"
3884
3885         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3886                 error "test1 still exists"
3887         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3888                 error "test2 still exists"
3889 }
3890 run_test 31p "remove of open striped directory"
3891
3892 test_31q() {
3893         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3894
3895         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3896         index=$($LFS getdirstripe -i $DIR/$tdir)
3897         [ $index -eq 3 ] || error "first stripe index $index != 3"
3898         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3899         [ $index -eq 1 ] || error "second stripe index $index != 1"
3900
3901         # when "-c <stripe_count>" is set, the number of MDTs specified after
3902         # "-i" should equal to the stripe count
3903         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3904 }
3905 run_test 31q "create striped directory on specific MDTs"
3906
3907 #LU-14949
3908 test_31r() {
3909         touch $DIR/$tfile.target
3910         touch $DIR/$tfile.source
3911
3912         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3913         $LCTL set_param fail_loc=0x1419 fail_val=3
3914         cat $DIR/$tfile.target &
3915         CATPID=$!
3916
3917         # Guarantee open is waiting before we get here
3918         sleep 1
3919         mv $DIR/$tfile.source $DIR/$tfile.target
3920
3921         wait $CATPID
3922         RC=$?
3923         if [[ $RC -ne 0 ]]; then
3924                 error "open with cat failed, rc=$RC"
3925         fi
3926 }
3927 run_test 31r "open-rename(replace) race"
3928
3929 cleanup_test32_mount() {
3930         local rc=0
3931         trap 0
3932         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3933         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3934         losetup -d $loopdev || true
3935         rm -rf $DIR/$tdir
3936         return $rc
3937 }
3938
3939 test_32a() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         echo "== more mountpoints and symlinks ================="
3943         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3944         trap cleanup_test32_mount EXIT
3945         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3946         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3947                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3948         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3949                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3950         cleanup_test32_mount
3951 }
3952 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3953
3954 test_32b() {
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3958         trap cleanup_test32_mount EXIT
3959         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3960         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3961                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3962         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3963                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3964         cleanup_test32_mount
3965 }
3966 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3967
3968 test_32c() {
3969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3970
3971         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3972         trap cleanup_test32_mount EXIT
3973         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3974         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3975                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3976         test_mkdir -p $DIR/$tdir/d2/test_dir
3977         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3978                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3979         cleanup_test32_mount
3980 }
3981 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3982
3983 test_32d() {
3984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3985
3986         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3987         trap cleanup_test32_mount EXIT
3988         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3989         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3990                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3991         test_mkdir -p $DIR/$tdir/d2/test_dir
3992         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3993                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3994         cleanup_test32_mount
3995 }
3996 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3997
3998 test_32e() {
3999         rm -fr $DIR/$tdir
4000         test_mkdir -p $DIR/$tdir/tmp
4001         local tmp_dir=$DIR/$tdir/tmp
4002         ln -s $DIR/$tdir $tmp_dir/symlink11
4003         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4004         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4005         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4006 }
4007 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4008
4009 test_32f() {
4010         rm -fr $DIR/$tdir
4011         test_mkdir -p $DIR/$tdir/tmp
4012         local tmp_dir=$DIR/$tdir/tmp
4013         ln -s $DIR/$tdir $tmp_dir/symlink11
4014         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4015         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4016         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4017 }
4018 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4019
4020 test_32g() {
4021         local tmp_dir=$DIR/$tdir/tmp
4022         test_mkdir -p $tmp_dir
4023         test_mkdir $DIR/${tdir}2
4024         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4025         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4026         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4027         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4028         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4029         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4030 }
4031 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4032
4033 test_32h() {
4034         rm -fr $DIR/$tdir $DIR/${tdir}2
4035         tmp_dir=$DIR/$tdir/tmp
4036         test_mkdir -p $tmp_dir
4037         test_mkdir $DIR/${tdir}2
4038         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4039         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4040         ls $tmp_dir/symlink12 || error "listing symlink12"
4041         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4042 }
4043 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4044
4045 test_32i() {
4046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4047
4048         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4049         trap cleanup_test32_mount EXIT
4050         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4051         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4052                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4053         touch $DIR/$tdir/test_file
4054         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4055                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4056         cleanup_test32_mount
4057 }
4058 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4059
4060 test_32j() {
4061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4062
4063         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4064         trap cleanup_test32_mount EXIT
4065         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4066         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4067                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4068         touch $DIR/$tdir/test_file
4069         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4070                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4071         cleanup_test32_mount
4072 }
4073 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4074
4075 test_32k() {
4076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4077
4078         rm -fr $DIR/$tdir
4079         trap cleanup_test32_mount EXIT
4080         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4081         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4082                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4083         test_mkdir -p $DIR/$tdir/d2
4084         touch $DIR/$tdir/d2/test_file || error "touch failed"
4085         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4086                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4087         cleanup_test32_mount
4088 }
4089 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4090
4091 test_32l() {
4092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4093
4094         rm -fr $DIR/$tdir
4095         trap cleanup_test32_mount EXIT
4096         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4097         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4098                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4099         test_mkdir -p $DIR/$tdir/d2
4100         touch $DIR/$tdir/d2/test_file || error "touch failed"
4101         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4102                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4103         cleanup_test32_mount
4104 }
4105 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4106
4107 test_32m() {
4108         rm -fr $DIR/d32m
4109         test_mkdir -p $DIR/d32m/tmp
4110         TMP_DIR=$DIR/d32m/tmp
4111         ln -s $DIR $TMP_DIR/symlink11
4112         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4113         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4114                 error "symlink11 not a link"
4115         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4116                 error "symlink01 not a link"
4117 }
4118 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4119
4120 test_32n() {
4121         rm -fr $DIR/d32n
4122         test_mkdir -p $DIR/d32n/tmp
4123         TMP_DIR=$DIR/d32n/tmp
4124         ln -s $DIR $TMP_DIR/symlink11
4125         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4126         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4127         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4128 }
4129 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4130
4131 test_32o() {
4132         touch $DIR/$tfile
4133         test_mkdir -p $DIR/d32o/tmp
4134         TMP_DIR=$DIR/d32o/tmp
4135         ln -s $DIR/$tfile $TMP_DIR/symlink12
4136         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4137         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4138                 error "symlink12 not a link"
4139         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4140         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4141                 error "$DIR/d32o/tmp/symlink12 not file type"
4142         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4143                 error "$DIR/d32o/symlink02 not file type"
4144 }
4145 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4146
4147 test_32p() {
4148         log 32p_1
4149         rm -fr $DIR/d32p
4150         log 32p_2
4151         rm -f $DIR/$tfile
4152         log 32p_3
4153         touch $DIR/$tfile
4154         log 32p_4
4155         test_mkdir -p $DIR/d32p/tmp
4156         log 32p_5
4157         TMP_DIR=$DIR/d32p/tmp
4158         log 32p_6
4159         ln -s $DIR/$tfile $TMP_DIR/symlink12
4160         log 32p_7
4161         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4162         log 32p_8
4163         cat $DIR/d32p/tmp/symlink12 ||
4164                 error "Can't open $DIR/d32p/tmp/symlink12"
4165         log 32p_9
4166         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4167         log 32p_10
4168 }
4169 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4170
4171 test_32q() {
4172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4173
4174         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4175         trap cleanup_test32_mount EXIT
4176         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4177         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4178         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4179                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4180         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4181         cleanup_test32_mount
4182 }
4183 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4184
4185 test_32r() {
4186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4187
4188         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4189         trap cleanup_test32_mount EXIT
4190         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4191         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4192         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4193                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4194         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4195         cleanup_test32_mount
4196 }
4197 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4198
4199 test_33aa() {
4200         rm -f $DIR/$tfile
4201         touch $DIR/$tfile
4202         chmod 444 $DIR/$tfile
4203         chown $RUNAS_ID $DIR/$tfile
4204         log 33_1
4205         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4206         log 33_2
4207 }
4208 run_test 33aa "write file with mode 444 (should return error)"
4209
4210 test_33a() {
4211         rm -fr $DIR/$tdir
4212         test_mkdir $DIR/$tdir
4213         chown $RUNAS_ID $DIR/$tdir
4214         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4215                 error "$RUNAS create $tdir/$tfile failed"
4216         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4217                 error "open RDWR" || true
4218 }
4219 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4220
4221 test_33b() {
4222         rm -fr $DIR/$tdir
4223         test_mkdir $DIR/$tdir
4224         chown $RUNAS_ID $DIR/$tdir
4225         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4226 }
4227 run_test 33b "test open file with malformed flags (No panic)"
4228
4229 test_33c() {
4230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4231         remote_ost_nodsh && skip "remote OST with nodsh"
4232
4233         local ostnum
4234         local ostname
4235         local write_bytes
4236         local all_zeros
4237
4238         all_zeros=true
4239         test_mkdir $DIR/$tdir
4240         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4241
4242         sync
4243         for ostnum in $(seq $OSTCOUNT); do
4244                 # test-framework's OST numbering is one-based, while Lustre's
4245                 # is zero-based
4246                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4247                 # check if at least some write_bytes stats are counted
4248                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4249                               obdfilter.$ostname.stats |
4250                               awk '/^write_bytes/ {print $7}' )
4251                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4252                 if (( ${write_bytes:-0} > 0 )); then
4253                         all_zeros=false
4254                         break
4255                 fi
4256         done
4257
4258         $all_zeros || return 0
4259
4260         # Write four bytes
4261         echo foo > $DIR/$tdir/bar
4262         # Really write them
4263         sync
4264
4265         # Total up write_bytes after writing.  We'd better find non-zeros.
4266         for ostnum in $(seq $OSTCOUNT); do
4267                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4268                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4269                               obdfilter/$ostname/stats |
4270                               awk '/^write_bytes/ {print $7}' )
4271                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4272                 if (( ${write_bytes:-0} > 0 )); then
4273                         all_zeros=false
4274                         break
4275                 fi
4276         done
4277
4278         if $all_zeros; then
4279                 for ostnum in $(seq $OSTCOUNT); do
4280                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4281                         echo "Check write_bytes is in obdfilter.*.stats:"
4282                         do_facet ost$ostnum lctl get_param -n \
4283                                 obdfilter.$ostname.stats
4284                 done
4285                 error "OST not keeping write_bytes stats (b=22312)"
4286         fi
4287 }
4288 run_test 33c "test write_bytes stats"
4289
4290 test_33d() {
4291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4293
4294         local MDTIDX=1
4295         local remote_dir=$DIR/$tdir/remote_dir
4296
4297         test_mkdir $DIR/$tdir
4298         $LFS mkdir -i $MDTIDX $remote_dir ||
4299                 error "create remote directory failed"
4300
4301         touch $remote_dir/$tfile
4302         chmod 444 $remote_dir/$tfile
4303         chown $RUNAS_ID $remote_dir/$tfile
4304
4305         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4306
4307         chown $RUNAS_ID $remote_dir
4308         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4309                                         error "create" || true
4310         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4311                                     error "open RDWR" || true
4312         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4313 }
4314 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4315
4316 test_33e() {
4317         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4318
4319         mkdir $DIR/$tdir
4320
4321         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4322         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4323         mkdir $DIR/$tdir/local_dir
4324
4325         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4326         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4327         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4328
4329         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4330                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4331
4332         rmdir $DIR/$tdir/* || error "rmdir failed"
4333
4334         umask 777
4335         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4336         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4337         mkdir $DIR/$tdir/local_dir
4338
4339         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4340         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4341         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4342
4343         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4344                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4345
4346         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4347
4348         umask 000
4349         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4350         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4351         mkdir $DIR/$tdir/local_dir
4352
4353         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4354         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4355         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4356
4357         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4358                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4359 }
4360 run_test 33e "mkdir and striped directory should have same mode"
4361
4362 cleanup_33f() {
4363         trap 0
4364         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4365 }
4366
4367 test_33f() {
4368         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4369         remote_mds_nodsh && skip "remote MDS with nodsh"
4370
4371         mkdir $DIR/$tdir
4372         chmod go+rwx $DIR/$tdir
4373         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4374         trap cleanup_33f EXIT
4375
4376         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4377                 error "cannot create striped directory"
4378
4379         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4380                 error "cannot create files in striped directory"
4381
4382         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4383                 error "cannot remove files in striped directory"
4384
4385         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4386                 error "cannot remove striped directory"
4387
4388         cleanup_33f
4389 }
4390 run_test 33f "nonroot user can create, access, and remove a striped directory"
4391
4392 test_33g() {
4393         mkdir -p $DIR/$tdir/dir2
4394
4395         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4396         echo $err
4397         [[ $err =~ "exists" ]] || error "Not exists error"
4398 }
4399 run_test 33g "nonroot user create already existing root created file"
4400
4401 sub_33h() {
4402         local hash_type=$1
4403         local count=250
4404
4405         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4406                 error "lfs mkdir -H $hash_type $tdir failed"
4407         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4408
4409         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4410         local index2
4411         local fname
4412
4413         for fname in $DIR/$tdir/$tfile.bak \
4414                      $DIR/$tdir/$tfile.SAV \
4415                      $DIR/$tdir/$tfile.orig \
4416                      $DIR/$tdir/$tfile~; do
4417                 touch $fname || error "touch $fname failed"
4418                 index2=$($LFS getstripe -m $fname)
4419                 (( $index == $index2 )) ||
4420                         error "$fname MDT index mismatch $index != $index2"
4421         done
4422
4423         local failed=0
4424         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4425         local pattern
4426
4427         for pattern in ${patterns[*]}; do
4428                 echo "pattern $pattern"
4429                 fname=$DIR/$tdir/$pattern
4430                 for (( i = 0; i < $count; i++ )); do
4431                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4432                                 error "mktemp $DIR/$tdir/$pattern failed"
4433                         index2=$($LFS getstripe -m $fname)
4434                         (( $index == $index2 )) && continue
4435
4436                         failed=$((failed + 1))
4437                         echo "$fname MDT index mismatch $index != $index2"
4438                 done
4439         done
4440
4441         echo "$failed/$count MDT index mismatches, expect ~2-4"
4442         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4443
4444         local same=0
4445         local expect
4446
4447         # verify that "crush" is still broken with all files on same MDT,
4448         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4449         [[ "$hash_type" == "crush" ]] && expect=$count ||
4450                 expect=$((count / MDSCOUNT))
4451
4452         # crush2 doesn't put all-numeric suffixes on the same MDT,
4453         # filename like $tfile.12345678 should *not* be considered temp
4454         for pattern in ${patterns[*]}; do
4455                 local base=${pattern%%X*}
4456                 local suff=${pattern#$base}
4457
4458                 echo "pattern $pattern"
4459                 for (( i = 0; i < $count; i++ )); do
4460                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4461                         touch $fname || error "touch $fname failed"
4462                         index2=$($LFS getstripe -m $fname)
4463                         (( $index != $index2 )) && continue
4464
4465                         same=$((same + 1))
4466                 done
4467         done
4468
4469         # the number of "bad" hashes is random, as it depends on the random
4470         # filenames generated by "mktemp".  Allow some margin in the results.
4471         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4472         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4473            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4474                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4475         same=0
4476
4477         # crush2 doesn't put suffixes with special characters on the same MDT
4478         # filename like $tfile.txt.1234 should *not* be considered temp
4479         for pattern in ${patterns[*]}; do
4480                 local base=${pattern%%X*}
4481                 local suff=${pattern#$base}
4482
4483                 pattern=$base...${suff/XXX}
4484                 echo "pattern=$pattern"
4485                 for (( i = 0; i < $count; i++ )); do
4486                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4487                                 error "touch $fname failed"
4488                         index2=$($LFS getstripe -m $fname)
4489                         (( $index != $index2 )) && continue
4490
4491                         same=$((same + 1))
4492                 done
4493         done
4494
4495         # the number of "bad" hashes is random, as it depends on the random
4496         # filenames generated by "mktemp".  Allow some margin in the results.
4497         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4498         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4499            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4500                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4501 }
4502
4503 test_33h() {
4504         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4505         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4506                 skip "Need MDS version at least 2.13.50"
4507
4508         sub_33h crush
4509 }
4510 run_test 33h "temp file is located on the same MDT as target (crush)"
4511
4512 test_33hh() {
4513         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4514         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4515         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4516                 skip "Need MDS version at least 2.15.0 for crush2"
4517
4518         sub_33h crush2
4519 }
4520 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4521
4522 test_33i()
4523 {
4524         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4525
4526         local FNAME=$(str_repeat 'f' 250)
4527
4528         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4529         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4530
4531         local count
4532         local total
4533
4534         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4535
4536         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4537
4538         lctl --device %$MDC deactivate
4539         stack_trap "lctl --device %$MDC activate"
4540         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4541         total=$(\ls -l $DIR/$tdir | wc -l)
4542         # "ls -l" will list total in the first line
4543         total=$((total - 1))
4544         (( total + count == 1000 )) ||
4545                 error "ls list $total files, $count files on MDT1"
4546 }
4547 run_test 33i "striped directory can be accessed when one MDT is down"
4548
4549 test_33j() {
4550         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4551
4552         mkdir -p $DIR/$tdir/
4553
4554         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4555                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4556
4557         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4558                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4559
4560         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4561                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4562
4563         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4564                 error "-D was not specified, but still failed"
4565 }
4566 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4567
4568 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4569 test_34a() {
4570         rm -f $DIR/f34
4571         $MCREATE $DIR/f34 || error "mcreate failed"
4572         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4573                 error "getstripe failed"
4574         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4575         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4576                 error "getstripe failed"
4577         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4578                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4579 }
4580 run_test 34a "truncate file that has not been opened ==========="
4581
4582 test_34b() {
4583         [ ! -f $DIR/f34 ] && test_34a
4584         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4585                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4586         $OPENFILE -f O_RDONLY $DIR/f34
4587         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4588                 error "getstripe failed"
4589         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4590                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4591 }
4592 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4593
4594 test_34c() {
4595         [ ! -f $DIR/f34 ] && test_34a
4596         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4597                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4598         $OPENFILE -f O_RDWR $DIR/f34
4599         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4600                 error "$LFS getstripe failed"
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4602                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4603 }
4604 run_test 34c "O_RDWR opening file-with-size works =============="
4605
4606 test_34d() {
4607         [ ! -f $DIR/f34 ] && test_34a
4608         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4609                 error "dd failed"
4610         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4611                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4612         rm $DIR/f34
4613 }
4614 run_test 34d "write to sparse file ============================="
4615
4616 test_34e() {
4617         rm -f $DIR/f34e
4618         $MCREATE $DIR/f34e || error "mcreate failed"
4619         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4620         $CHECKSTAT -s 1000 $DIR/f34e ||
4621                 error "Size of $DIR/f34e not equal to 1000 bytes"
4622         $OPENFILE -f O_RDWR $DIR/f34e
4623         $CHECKSTAT -s 1000 $DIR/f34e ||
4624                 error "Size of $DIR/f34e not equal to 1000 bytes"
4625 }
4626 run_test 34e "create objects, some with size and some without =="
4627
4628 test_34f() { # bug 6242, 6243
4629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4630
4631         SIZE34F=48000
4632         rm -f $DIR/f34f
4633         $MCREATE $DIR/f34f || error "mcreate failed"
4634         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4635         dd if=$DIR/f34f of=$TMP/f34f
4636         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4637         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4638         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4639         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4640         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4641 }
4642 run_test 34f "read from a file with no objects until EOF ======="
4643
4644 test_34g() {
4645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4646
4647         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4648                 error "dd failed"
4649         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4650         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4651                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4652         cancel_lru_locks osc
4653         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4654                 error "wrong size after lock cancel"
4655
4656         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4657         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4658                 error "expanding truncate failed"
4659         cancel_lru_locks osc
4660         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4661                 error "wrong expanded size after lock cancel"
4662 }
4663 run_test 34g "truncate long file ==============================="
4664
4665 test_34h() {
4666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4667
4668         local gid=10
4669         local sz=1000
4670
4671         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4672         sync # Flush the cache so that multiop below does not block on cache
4673              # flush when getting the group lock
4674         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4675         MULTIPID=$!
4676
4677         # Since just timed wait is not good enough, let's do a sync write
4678         # that way we are sure enough time for a roundtrip + processing
4679         # passed + 2 seconds of extra margin.
4680         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4681         rm $DIR/${tfile}-1
4682         sleep 2
4683
4684         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4685                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4686                 kill -9 $MULTIPID
4687         fi
4688         wait $MULTIPID
4689         local nsz=`stat -c %s $DIR/$tfile`
4690         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4691 }
4692 run_test 34h "ftruncate file under grouplock should not block"
4693
4694 test_35a() {
4695         cp /bin/sh $DIR/f35a
4696         chmod 444 $DIR/f35a
4697         chown $RUNAS_ID $DIR/f35a
4698         $RUNAS $DIR/f35a && error || true
4699         rm $DIR/f35a
4700 }
4701 run_test 35a "exec file with mode 444 (should return and not leak)"
4702
4703 test_36a() {
4704         rm -f $DIR/f36
4705         utime $DIR/f36 || error "utime failed for MDS"
4706 }
4707 run_test 36a "MDS utime check (mknod, utime)"
4708
4709 test_36b() {
4710         echo "" > $DIR/f36
4711         utime $DIR/f36 || error "utime failed for OST"
4712 }
4713 run_test 36b "OST utime check (open, utime)"
4714
4715 test_36c() {
4716         rm -f $DIR/d36/f36
4717         test_mkdir $DIR/d36
4718         chown $RUNAS_ID $DIR/d36
4719         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4720 }
4721 run_test 36c "non-root MDS utime check (mknod, utime)"
4722
4723 test_36d() {
4724         [ ! -d $DIR/d36 ] && test_36c
4725         echo "" > $DIR/d36/f36
4726         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4727 }
4728 run_test 36d "non-root OST utime check (open, utime)"
4729
4730 test_36e() {
4731         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4732
4733         test_mkdir $DIR/$tdir
4734         touch $DIR/$tdir/$tfile
4735         $RUNAS utime $DIR/$tdir/$tfile &&
4736                 error "utime worked, expected failure" || true
4737 }
4738 run_test 36e "utime on non-owned file (should return error)"
4739
4740 subr_36fh() {
4741         local fl="$1"
4742         local LANG_SAVE=$LANG
4743         local LC_LANG_SAVE=$LC_LANG
4744         export LANG=C LC_LANG=C # for date language
4745
4746         DATESTR="Dec 20  2000"
4747         test_mkdir $DIR/$tdir
4748         lctl set_param fail_loc=$fl
4749         date; date +%s
4750         cp /etc/hosts $DIR/$tdir/$tfile
4751         sync & # write RPC generated with "current" inode timestamp, but delayed
4752         sleep 1
4753         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4754         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4755         cancel_lru_locks $OSC
4756         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4757         date; date +%s
4758         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4759                 echo "BEFORE: $LS_BEFORE" && \
4760                 echo "AFTER : $LS_AFTER" && \
4761                 echo "WANT  : $DATESTR" && \
4762                 error "$DIR/$tdir/$tfile timestamps changed" || true
4763
4764         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4765 }
4766
4767 test_36f() {
4768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4769
4770         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4771         subr_36fh "0x80000214"
4772 }
4773 run_test 36f "utime on file racing with OST BRW write =========="
4774
4775 test_36g() {
4776         remote_ost_nodsh && skip "remote OST with nodsh"
4777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4778         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4779                 skip "Need MDS version at least 2.12.51"
4780
4781         local fmd_max_age
4782         local fmd
4783         local facet="ost1"
4784         local tgt="obdfilter"
4785
4786         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4787
4788         test_mkdir $DIR/$tdir
4789         fmd_max_age=$(do_facet $facet \
4790                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4791                 head -n 1")
4792
4793         echo "FMD max age: ${fmd_max_age}s"
4794         touch $DIR/$tdir/$tfile
4795         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4796                 gawk '{cnt=cnt+$1}  END{print cnt}')
4797         echo "FMD before: $fmd"
4798         [[ $fmd == 0 ]] &&
4799                 error "FMD wasn't create by touch"
4800         sleep $((fmd_max_age + 12))
4801         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4802                 gawk '{cnt=cnt+$1}  END{print cnt}')
4803         echo "FMD after: $fmd"
4804         [[ $fmd == 0 ]] ||
4805                 error "FMD wasn't expired by ping"
4806 }
4807 run_test 36g "FMD cache expiry ====================="
4808
4809 test_36h() {
4810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4811
4812         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4813         subr_36fh "0x80000227"
4814 }
4815 run_test 36h "utime on file racing with OST BRW write =========="
4816
4817 test_36i() {
4818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4819
4820         test_mkdir $DIR/$tdir
4821         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4822
4823         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4824         local new_mtime=$((mtime + 200))
4825
4826         #change Modify time of striped dir
4827         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4828                         error "change mtime failed"
4829
4830         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4831
4832         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4833 }
4834 run_test 36i "change mtime on striped directory"
4835
4836 # test_37 - duplicate with tests 32q 32r
4837
4838 test_38() {
4839         local file=$DIR/$tfile
4840         touch $file
4841         openfile -f O_DIRECTORY $file
4842         local RC=$?
4843         local ENOTDIR=20
4844         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4845         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4846 }
4847 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4848
4849 test_39a() { # was test_39
4850         touch $DIR/$tfile
4851         touch $DIR/${tfile}2
4852 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4853 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4854 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4855         sleep 2
4856         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4857         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4858                 echo "mtime"
4859                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4860                 echo "atime"
4861                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4862                 echo "ctime"
4863                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4864                 error "O_TRUNC didn't change timestamps"
4865         fi
4866 }
4867 run_test 39a "mtime changed on create"
4868
4869 test_39b() {
4870         test_mkdir -c1 $DIR/$tdir
4871         cp -p /etc/passwd $DIR/$tdir/fopen
4872         cp -p /etc/passwd $DIR/$tdir/flink
4873         cp -p /etc/passwd $DIR/$tdir/funlink
4874         cp -p /etc/passwd $DIR/$tdir/frename
4875         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4876
4877         sleep 1
4878         echo "aaaaaa" >> $DIR/$tdir/fopen
4879         echo "aaaaaa" >> $DIR/$tdir/flink
4880         echo "aaaaaa" >> $DIR/$tdir/funlink
4881         echo "aaaaaa" >> $DIR/$tdir/frename
4882
4883         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4884         local link_new=`stat -c %Y $DIR/$tdir/flink`
4885         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4886         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4887
4888         cat $DIR/$tdir/fopen > /dev/null
4889         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4890         rm -f $DIR/$tdir/funlink2
4891         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4892
4893         for (( i=0; i < 2; i++ )) ; do
4894                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4895                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4896                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4897                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4898
4899                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4900                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4901                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4902                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4903
4904                 cancel_lru_locks $OSC
4905                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4906         done
4907 }
4908 run_test 39b "mtime change on open, link, unlink, rename  ======"
4909
4910 # this should be set to past
4911 TEST_39_MTIME=`date -d "1 year ago" +%s`
4912
4913 # bug 11063
4914 test_39c() {
4915         touch $DIR1/$tfile
4916         sleep 2
4917         local mtime0=`stat -c %Y $DIR1/$tfile`
4918
4919         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4920         local mtime1=`stat -c %Y $DIR1/$tfile`
4921         [ "$mtime1" = $TEST_39_MTIME ] || \
4922                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4923
4924         local d1=`date +%s`
4925         echo hello >> $DIR1/$tfile
4926         local d2=`date +%s`
4927         local mtime2=`stat -c %Y $DIR1/$tfile`
4928         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4929                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4930
4931         mv $DIR1/$tfile $DIR1/$tfile-1
4932
4933         for (( i=0; i < 2; i++ )) ; do
4934                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4935                 [ "$mtime2" = "$mtime3" ] || \
4936                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4937
4938                 cancel_lru_locks $OSC
4939                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4940         done
4941 }
4942 run_test 39c "mtime change on rename ==========================="
4943
4944 # bug 21114
4945 test_39d() {
4946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4947
4948         touch $DIR1/$tfile
4949         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4950
4951         for (( i=0; i < 2; i++ )) ; do
4952                 local mtime=`stat -c %Y $DIR1/$tfile`
4953                 [ $mtime = $TEST_39_MTIME ] || \
4954                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4955
4956                 cancel_lru_locks $OSC
4957                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4958         done
4959 }
4960 run_test 39d "create, utime, stat =============================="
4961
4962 # bug 21114
4963 test_39e() {
4964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4965
4966         touch $DIR1/$tfile
4967         local mtime1=`stat -c %Y $DIR1/$tfile`
4968
4969         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4970
4971         for (( i=0; i < 2; i++ )) ; do
4972                 local mtime2=`stat -c %Y $DIR1/$tfile`
4973                 [ $mtime2 = $TEST_39_MTIME ] || \
4974                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4975
4976                 cancel_lru_locks $OSC
4977                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4978         done
4979 }
4980 run_test 39e "create, stat, utime, stat ========================"
4981
4982 # bug 21114
4983 test_39f() {
4984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4985
4986         touch $DIR1/$tfile
4987         mtime1=`stat -c %Y $DIR1/$tfile`
4988
4989         sleep 2
4990         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4991
4992         for (( i=0; i < 2; i++ )) ; do
4993                 local mtime2=`stat -c %Y $DIR1/$tfile`
4994                 [ $mtime2 = $TEST_39_MTIME ] || \
4995                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4996
4997                 cancel_lru_locks $OSC
4998                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4999         done
5000 }
5001 run_test 39f "create, stat, sleep, utime, stat ================="
5002
5003 # bug 11063
5004 test_39g() {
5005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5006
5007         echo hello >> $DIR1/$tfile
5008         local mtime1=`stat -c %Y $DIR1/$tfile`
5009
5010         sleep 2
5011         chmod o+r $DIR1/$tfile
5012
5013         for (( i=0; i < 2; i++ )) ; do
5014                 local mtime2=`stat -c %Y $DIR1/$tfile`
5015                 [ "$mtime1" = "$mtime2" ] || \
5016                         error "lost mtime: $mtime2, should be $mtime1"
5017
5018                 cancel_lru_locks $OSC
5019                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5020         done
5021 }
5022 run_test 39g "write, chmod, stat ==============================="
5023
5024 # bug 11063
5025 test_39h() {
5026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5027
5028         touch $DIR1/$tfile
5029         sleep 1
5030
5031         local d1=`date`
5032         echo hello >> $DIR1/$tfile
5033         local mtime1=`stat -c %Y $DIR1/$tfile`
5034
5035         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5036         local d2=`date`
5037         if [ "$d1" != "$d2" ]; then
5038                 echo "write and touch not within one second"
5039         else
5040                 for (( i=0; i < 2; i++ )) ; do
5041                         local mtime2=`stat -c %Y $DIR1/$tfile`
5042                         [ "$mtime2" = $TEST_39_MTIME ] || \
5043                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5044
5045                         cancel_lru_locks $OSC
5046                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5047                 done
5048         fi
5049 }
5050 run_test 39h "write, utime within one second, stat ============="
5051
5052 test_39i() {
5053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5054
5055         touch $DIR1/$tfile
5056         sleep 1
5057
5058         echo hello >> $DIR1/$tfile
5059         local mtime1=`stat -c %Y $DIR1/$tfile`
5060
5061         mv $DIR1/$tfile $DIR1/$tfile-1
5062
5063         for (( i=0; i < 2; i++ )) ; do
5064                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5065
5066                 [ "$mtime1" = "$mtime2" ] || \
5067                         error "lost mtime: $mtime2, should be $mtime1"
5068
5069                 cancel_lru_locks $OSC
5070                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5071         done
5072 }
5073 run_test 39i "write, rename, stat =============================="
5074
5075 test_39j() {
5076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5077
5078         start_full_debug_logging
5079         touch $DIR1/$tfile
5080         sleep 1
5081
5082         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5083         lctl set_param fail_loc=0x80000412
5084         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5085                 error "multiop failed"
5086         local multipid=$!
5087         local mtime1=`stat -c %Y $DIR1/$tfile`
5088
5089         mv $DIR1/$tfile $DIR1/$tfile-1
5090
5091         kill -USR1 $multipid
5092         wait $multipid || error "multiop close failed"
5093
5094         for (( i=0; i < 2; i++ )) ; do
5095                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5096                 [ "$mtime1" = "$mtime2" ] ||
5097                         error "mtime is lost on close: $mtime2, " \
5098                               "should be $mtime1"
5099
5100                 cancel_lru_locks
5101                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5102         done
5103         lctl set_param fail_loc=0
5104         stop_full_debug_logging
5105 }
5106 run_test 39j "write, rename, close, stat ======================="
5107
5108 test_39k() {
5109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5110
5111         touch $DIR1/$tfile
5112         sleep 1
5113
5114         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5115         local multipid=$!
5116         local mtime1=`stat -c %Y $DIR1/$tfile`
5117
5118         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5119
5120         kill -USR1 $multipid
5121         wait $multipid || error "multiop close failed"
5122
5123         for (( i=0; i < 2; i++ )) ; do
5124                 local mtime2=`stat -c %Y $DIR1/$tfile`
5125
5126                 [ "$mtime2" = $TEST_39_MTIME ] || \
5127                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5128
5129                 cancel_lru_locks
5130                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5131         done
5132 }
5133 run_test 39k "write, utime, close, stat ========================"
5134
5135 # this should be set to future
5136 TEST_39_ATIME=`date -d "1 year" +%s`
5137
5138 test_39l() {
5139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5140         remote_mds_nodsh && skip "remote MDS with nodsh"
5141
5142         local atime_diff=$(do_facet $SINGLEMDS \
5143                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5144         rm -rf $DIR/$tdir
5145         mkdir_on_mdt0 $DIR/$tdir
5146
5147         # test setting directory atime to future
5148         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5149         local atime=$(stat -c %X $DIR/$tdir)
5150         [ "$atime" = $TEST_39_ATIME ] ||
5151                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5152
5153         # test setting directory atime from future to now
5154         local now=$(date +%s)
5155         touch -a -d @$now $DIR/$tdir
5156
5157         atime=$(stat -c %X $DIR/$tdir)
5158         [ "$atime" -eq "$now"  ] ||
5159                 error "atime is not updated from future: $atime, $now"
5160
5161         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5162         sleep 3
5163
5164         # test setting directory atime when now > dir atime + atime_diff
5165         local d1=$(date +%s)
5166         ls $DIR/$tdir
5167         local d2=$(date +%s)
5168         cancel_lru_locks mdc
5169         atime=$(stat -c %X $DIR/$tdir)
5170         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5171                 error "atime is not updated  : $atime, should be $d2"
5172
5173         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5174         sleep 3
5175
5176         # test not setting directory atime when now < dir atime + atime_diff
5177         ls $DIR/$tdir
5178         cancel_lru_locks mdc
5179         atime=$(stat -c %X $DIR/$tdir)
5180         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5181                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5182
5183         do_facet $SINGLEMDS \
5184                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5185 }
5186 run_test 39l "directory atime update ==========================="
5187
5188 test_39m() {
5189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5190
5191         touch $DIR1/$tfile
5192         sleep 2
5193         local far_past_mtime=$(date -d "May 29 1953" +%s)
5194         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5195
5196         touch -m -d @$far_past_mtime $DIR1/$tfile
5197         touch -a -d @$far_past_atime $DIR1/$tfile
5198
5199         for (( i=0; i < 2; i++ )) ; do
5200                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5201                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5202                         error "atime or mtime set incorrectly"
5203
5204                 cancel_lru_locks $OSC
5205                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5206         done
5207 }
5208 run_test 39m "test atime and mtime before 1970"
5209
5210 test_39n() { # LU-3832
5211         remote_mds_nodsh && skip "remote MDS with nodsh"
5212
5213         local atime_diff=$(do_facet $SINGLEMDS \
5214                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5215         local atime0
5216         local atime1
5217         local atime2
5218
5219         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5220
5221         rm -rf $DIR/$tfile
5222         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5223         atime0=$(stat -c %X $DIR/$tfile)
5224
5225         sleep 5
5226         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5227         atime1=$(stat -c %X $DIR/$tfile)
5228
5229         sleep 5
5230         cancel_lru_locks mdc
5231         cancel_lru_locks osc
5232         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5233         atime2=$(stat -c %X $DIR/$tfile)
5234
5235         do_facet $SINGLEMDS \
5236                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5237
5238         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5239         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5240 }
5241 run_test 39n "check that O_NOATIME is honored"
5242
5243 test_39o() {
5244         TESTDIR=$DIR/$tdir/$tfile
5245         [ -e $TESTDIR ] && rm -rf $TESTDIR
5246         mkdir -p $TESTDIR
5247         cd $TESTDIR
5248         links1=2
5249         ls
5250         mkdir a b
5251         ls
5252         links2=$(stat -c %h .)
5253         [ $(($links1 + 2)) != $links2 ] &&
5254                 error "wrong links count $(($links1 + 2)) != $links2"
5255         rmdir b
5256         links3=$(stat -c %h .)
5257         [ $(($links1 + 1)) != $links3 ] &&
5258                 error "wrong links count $links1 != $links3"
5259         return 0
5260 }
5261 run_test 39o "directory cached attributes updated after create"
5262
5263 test_39p() {
5264         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5265
5266         local MDTIDX=1
5267         TESTDIR=$DIR/$tdir/$tdir
5268         [ -e $TESTDIR ] && rm -rf $TESTDIR
5269         test_mkdir -p $TESTDIR
5270         cd $TESTDIR
5271         links1=2
5272         ls
5273         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5274         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5275         ls
5276         links2=$(stat -c %h .)
5277         [ $(($links1 + 2)) != $links2 ] &&
5278                 error "wrong links count $(($links1 + 2)) != $links2"
5279         rmdir remote_dir2
5280         links3=$(stat -c %h .)
5281         [ $(($links1 + 1)) != $links3 ] &&
5282                 error "wrong links count $links1 != $links3"
5283         return 0
5284 }
5285 run_test 39p "remote directory cached attributes updated after create ========"
5286
5287 test_39r() {
5288         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5289                 skip "no atime update on old OST"
5290         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5291                 skip_env "ldiskfs only test"
5292         fi
5293
5294         local saved_adiff
5295         local ahost=$(facet_active_host ost1)
5296         saved_adiff=$(do_facet ost1 \
5297                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5298         stack_trap "do_facet ost1 \
5299                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5300
5301         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5302
5303         $LFS setstripe -i 0 $DIR/$tfile
5304         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5305                 error "can't write initial file"
5306         cancel_lru_locks osc
5307
5308         # exceed atime_diff and access file
5309         sleep 10
5310         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5311                 error "can't udpate atime"
5312
5313         # atime_cli value is in decimal
5314         local atime_cli=$(stat -c %X $DIR/$tfile)
5315         echo "client atime: $atime_cli"
5316
5317         local ostdev=$(ostdevname 1)
5318         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5319         local seq=${fid[3]#0x}
5320         local oid=${fid[1]}
5321         local oid_hex
5322
5323         if [ $seq == 0 ]; then
5324                 oid_hex=${fid[1]}
5325         else
5326                 oid_hex=${fid[2]#0x}
5327         fi
5328         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5329         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5330
5331         # allow atime update to be written to device
5332         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5333         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5334
5335         # Give enough time for server to get updated. Until then
5336         # the value read is defaulted to "0x00000000:00000000"
5337         # Wait until atime read via debugfs is not equal to zero.
5338         # Max limit to wait is 30 seconds.
5339         wait_update_cond $ahost                                         \
5340                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5341                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5342         # atime_ost value is in hex
5343         local atime_ost=$(do_facet ost1 "$cmd" |&
5344                           awk -F'[: ]' '/atime:/ { print $4 }')
5345         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5346         # convert Hex to decimal before comparing
5347         local atime_ost_dec=$((atime_ost))
5348
5349         # The test pass criteria is that the client time and server should
5350         # be same (2s gap accepted). This gap could arise due to VFS updating
5351         # the atime after the read(dd), stat and the updated time from the
5352         # inode
5353         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5354                 error "atime on client $atime_cli != ost $atime_ost_dec"
5355 }
5356 run_test 39r "lazy atime update on OST"
5357
5358 test_39q() { # LU-8041
5359         local testdir=$DIR/$tdir
5360         mkdir -p $testdir
5361         multiop_bg_pause $testdir D_c || error "multiop failed"
5362         local multipid=$!
5363         cancel_lru_locks mdc
5364         kill -USR1 $multipid
5365         local atime=$(stat -c %X $testdir)
5366         [ "$atime" -ne 0 ] || error "atime is zero"
5367 }
5368 run_test 39q "close won't zero out atime"
5369
5370 test_39s() {
5371         local atime0
5372         local atime1
5373         local atime2
5374         local atime3
5375         local atime4
5376
5377         umount_client $MOUNT
5378         mount_client $MOUNT relatime
5379
5380         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5381         atime0=$(stat -c %X $DIR/$tfile)
5382
5383         # First read updates atime
5384         sleep 1
5385         cat $DIR/$tfile >/dev/null
5386         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5387
5388         # Next reads do not update atime
5389         sleep 1
5390         cat $DIR/$tfile >/dev/null
5391         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5392
5393         # If mtime is greater than atime, atime is updated
5394         sleep 1
5395         touch -m $DIR/$tfile # (mtime = now)
5396         sleep 1
5397         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5398         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5399
5400         # Next reads do not update atime
5401         sleep 1
5402         cat $DIR/$tfile >/dev/null
5403         atime4=$(stat -c %X $DIR/$tfile)
5404
5405         # Remount the client to clear 'relatime' option
5406         remount_client $MOUNT
5407
5408         (( atime0 < atime1 )) ||
5409                 error "atime $atime0 should be smaller than $atime1"
5410         (( atime1 == atime2 )) ||
5411                 error "atime $atime1 was updated to $atime2"
5412         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5413         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5414 }
5415 run_test 39s "relatime is supported"
5416
5417 test_40() {
5418         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5419         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5420                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5421         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5422                 error "$tfile is not 4096 bytes in size"
5423 }
5424 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5425
5426 test_41() {
5427         # bug 1553
5428         small_write $DIR/f41 18
5429 }
5430 run_test 41 "test small file write + fstat ====================="
5431
5432 count_ost_writes() {
5433         lctl get_param -n ${OSC}.*.stats |
5434                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5435                         END { printf("%0.0f", writes) }'
5436 }
5437
5438 # decent default
5439 WRITEBACK_SAVE=500
5440 DIRTY_RATIO_SAVE=40
5441 MAX_DIRTY_RATIO=50
5442 BG_DIRTY_RATIO_SAVE=10
5443 MAX_BG_DIRTY_RATIO=25
5444
5445 start_writeback() {
5446         trap 0
5447         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5448         # dirty_ratio, dirty_background_ratio
5449         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5450                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5451                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5452                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5453         else
5454                 # if file not here, we are a 2.4 kernel
5455                 kill -CONT `pidof kupdated`
5456         fi
5457 }
5458
5459 stop_writeback() {
5460         # setup the trap first, so someone cannot exit the test at the
5461         # exact wrong time and mess up a machine
5462         trap start_writeback EXIT
5463         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5464         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5465                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5466                 sysctl -w vm.dirty_writeback_centisecs=0
5467                 sysctl -w vm.dirty_writeback_centisecs=0
5468                 # save and increase /proc/sys/vm/dirty_ratio
5469                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5470                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5471                 # save and increase /proc/sys/vm/dirty_background_ratio
5472                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5473                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5474         else
5475                 # if file not here, we are a 2.4 kernel
5476                 kill -STOP `pidof kupdated`
5477         fi
5478 }
5479
5480 # ensure that all stripes have some grant before we test client-side cache
5481 setup_test42() {
5482         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5483                 dd if=/dev/zero of=$i bs=4k count=1
5484                 rm $i
5485         done
5486 }
5487
5488 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5489 # file truncation, and file removal.
5490 test_42a() {
5491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5492
5493         setup_test42
5494         cancel_lru_locks $OSC
5495         stop_writeback
5496         sync; sleep 1; sync # just to be safe
5497         BEFOREWRITES=`count_ost_writes`
5498         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5499         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5500         AFTERWRITES=`count_ost_writes`
5501         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5502                 error "$BEFOREWRITES < $AFTERWRITES"
5503         start_writeback
5504 }
5505 run_test 42a "ensure that we don't flush on close"
5506
5507 test_42b() {
5508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5509
5510         setup_test42
5511         cancel_lru_locks $OSC
5512         stop_writeback
5513         sync
5514         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5515         BEFOREWRITES=$(count_ost_writes)
5516         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5517         AFTERWRITES=$(count_ost_writes)
5518         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5519                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5520         fi
5521         BEFOREWRITES=$(count_ost_writes)
5522         sync || error "sync: $?"
5523         AFTERWRITES=$(count_ost_writes)
5524         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5525                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5526         fi
5527         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5528         start_writeback
5529         return 0
5530 }
5531 run_test 42b "test destroy of file with cached dirty data ======"
5532
5533 # if these tests just want to test the effect of truncation,
5534 # they have to be very careful.  consider:
5535 # - the first open gets a {0,EOF}PR lock
5536 # - the first write conflicts and gets a {0, count-1}PW
5537 # - the rest of the writes are under {count,EOF}PW
5538 # - the open for truncate tries to match a {0,EOF}PR
5539 #   for the filesize and cancels the PWs.
5540 # any number of fixes (don't get {0,EOF} on open, match
5541 # composite locks, do smarter file size management) fix
5542 # this, but for now we want these tests to verify that
5543 # the cancellation with truncate intent works, so we
5544 # start the file with a full-file pw lock to match against
5545 # until the truncate.
5546 trunc_test() {
5547         test=$1
5548         file=$DIR/$test
5549         offset=$2
5550         cancel_lru_locks $OSC
5551         stop_writeback
5552         # prime the file with 0,EOF PW to match
5553         touch $file
5554         $TRUNCATE $file 0
5555         sync; sync
5556         # now the real test..
5557         dd if=/dev/zero of=$file bs=1024 count=100
5558         BEFOREWRITES=`count_ost_writes`
5559         $TRUNCATE $file $offset
5560         cancel_lru_locks $OSC
5561         AFTERWRITES=`count_ost_writes`
5562         start_writeback
5563 }
5564
5565 test_42c() {
5566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5567
5568         trunc_test 42c 1024
5569         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5570                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5571         rm $file
5572 }
5573 run_test 42c "test partial truncate of file with cached dirty data"
5574
5575 test_42d() {
5576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5577
5578         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5579         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5580         $LCTL set_param debug=+cache
5581
5582         trunc_test 42d 0
5583         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5584                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5585         rm $file
5586 }
5587 run_test 42d "test complete truncate of file with cached dirty data"
5588
5589 test_42e() { # bug22074
5590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5591
5592         local TDIR=$DIR/${tdir}e
5593         local pages=16 # hardcoded 16 pages, don't change it.
5594         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5595         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5596         local max_dirty_mb
5597         local warmup_files
5598
5599         test_mkdir $DIR/${tdir}e
5600         $LFS setstripe -c 1 $TDIR
5601         createmany -o $TDIR/f $files
5602
5603         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5604
5605         # we assume that with $OSTCOUNT files, at least one of them will
5606         # be allocated on OST0.
5607         warmup_files=$((OSTCOUNT * max_dirty_mb))
5608         createmany -o $TDIR/w $warmup_files
5609
5610         # write a large amount of data into one file and sync, to get good
5611         # avail_grant number from OST.
5612         for ((i=0; i<$warmup_files; i++)); do
5613                 idx=$($LFS getstripe -i $TDIR/w$i)
5614                 [ $idx -ne 0 ] && continue
5615                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5616                 break
5617         done
5618         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5619         sync
5620         $LCTL get_param $proc_osc0/cur_dirty_bytes
5621         $LCTL get_param $proc_osc0/cur_grant_bytes
5622
5623         # create as much dirty pages as we can while not to trigger the actual
5624         # RPCs directly. but depends on the env, VFS may trigger flush during this
5625         # period, hopefully we are good.
5626         for ((i=0; i<$warmup_files; i++)); do
5627                 idx=$($LFS getstripe -i $TDIR/w$i)
5628                 [ $idx -ne 0 ] && continue
5629                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5630         done
5631         $LCTL get_param $proc_osc0/cur_dirty_bytes
5632         $LCTL get_param $proc_osc0/cur_grant_bytes
5633
5634         # perform the real test
5635         $LCTL set_param $proc_osc0/rpc_stats 0
5636         for ((;i<$files; i++)); do
5637                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5638                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5639         done
5640         sync
5641         $LCTL get_param $proc_osc0/rpc_stats
5642
5643         local percent=0
5644         local have_ppr=false
5645         $LCTL get_param $proc_osc0/rpc_stats |
5646                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5647                         # skip lines until we are at the RPC histogram data
5648                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5649                         $have_ppr || continue
5650
5651                         # we only want the percent stat for < 16 pages
5652                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5653
5654                         percent=$((percent + WPCT))
5655                         if [[ $percent -gt 15 ]]; then
5656                                 error "less than 16-pages write RPCs" \
5657                                       "$percent% > 15%"
5658                                 break
5659                         fi
5660                 done
5661         rm -rf $TDIR
5662 }
5663 run_test 42e "verify sub-RPC writes are not done synchronously"
5664
5665 test_43A() { # was test_43
5666         test_mkdir $DIR/$tdir
5667         cp -p /bin/ls $DIR/$tdir/$tfile
5668         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5669         pid=$!
5670         # give multiop a chance to open
5671         sleep 1
5672
5673         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5674         kill -USR1 $pid
5675         # Wait for multiop to exit
5676         wait $pid
5677 }
5678 run_test 43A "execution of file opened for write should return -ETXTBSY"
5679
5680 test_43a() {
5681         test_mkdir $DIR/$tdir
5682         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5683         $DIR/$tdir/sleep 60 &
5684         SLEEP_PID=$!
5685         # Make sure exec of $tdir/sleep wins race with truncate
5686         sleep 1
5687         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5688         kill $SLEEP_PID
5689 }
5690 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5691
5692 test_43b() {
5693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5694
5695         test_mkdir $DIR/$tdir
5696         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5697         $DIR/$tdir/sleep 60 &
5698         SLEEP_PID=$!
5699         # Make sure exec of $tdir/sleep wins race with truncate
5700         sleep 1
5701         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5702         kill $SLEEP_PID
5703 }
5704 run_test 43b "truncate of file being executed should return -ETXTBSY"
5705
5706 test_43c() {
5707         local testdir="$DIR/$tdir"
5708         test_mkdir $testdir
5709         cp $SHELL $testdir/
5710         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5711                 ( cd $testdir && md5sum -c )
5712 }
5713 run_test 43c "md5sum of copy into lustre"
5714
5715 test_44A() { # was test_44
5716         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5717
5718         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5719         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5720 }
5721 run_test 44A "zero length read from a sparse stripe"
5722
5723 test_44a() {
5724         local nstripe=$($LFS getstripe -c -d $DIR)
5725         [ -z "$nstripe" ] && skip "can't get stripe info"
5726         [[ $nstripe -gt $OSTCOUNT ]] &&
5727                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5728
5729         local stride=$($LFS getstripe -S -d $DIR)
5730         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5731                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5732         fi
5733
5734         OFFSETS="0 $((stride/2)) $((stride-1))"
5735         for offset in $OFFSETS; do
5736                 for i in $(seq 0 $((nstripe-1))); do
5737                         local GLOBALOFFSETS=""
5738                         # size in Bytes
5739                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5740                         local myfn=$DIR/d44a-$size
5741                         echo "--------writing $myfn at $size"
5742                         ll_sparseness_write $myfn $size ||
5743                                 error "ll_sparseness_write"
5744                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5745                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5746                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5747
5748                         for j in $(seq 0 $((nstripe-1))); do
5749                                 # size in Bytes
5750                                 size=$((((j + $nstripe )*$stride + $offset)))
5751                                 ll_sparseness_write $myfn $size ||
5752                                         error "ll_sparseness_write"
5753                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5754                         done
5755                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5756                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5757                         rm -f $myfn
5758                 done
5759         done
5760 }
5761 run_test 44a "test sparse pwrite ==============================="
5762
5763 dirty_osc_total() {
5764         tot=0
5765         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5766                 tot=$(($tot + $d))
5767         done
5768         echo $tot
5769 }
5770 do_dirty_record() {
5771         before=`dirty_osc_total`
5772         echo executing "\"$*\""
5773         eval $*
5774         after=`dirty_osc_total`
5775         echo before $before, after $after
5776 }
5777 test_45() {
5778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5779
5780         f="$DIR/f45"
5781         # Obtain grants from OST if it supports it
5782         echo blah > ${f}_grant
5783         stop_writeback
5784         sync
5785         do_dirty_record "echo blah > $f"
5786         [[ $before -eq $after ]] && error "write wasn't cached"
5787         do_dirty_record "> $f"
5788         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5789         do_dirty_record "echo blah > $f"
5790         [[ $before -eq $after ]] && error "write wasn't cached"
5791         do_dirty_record "sync"
5792         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5793         do_dirty_record "echo blah > $f"
5794         [[ $before -eq $after ]] && error "write wasn't cached"
5795         do_dirty_record "cancel_lru_locks osc"
5796         [[ $before -gt $after ]] ||
5797                 error "lock cancellation didn't lower dirty count"
5798         start_writeback
5799 }
5800 run_test 45 "osc io page accounting ============================"
5801
5802 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5803 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5804 # objects offset and an assert hit when an rpc was built with 1023's mapped
5805 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5806 test_46() {
5807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5808
5809         f="$DIR/f46"
5810         stop_writeback
5811         sync
5812         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5813         sync
5814         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5815         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5816         sync
5817         start_writeback
5818 }
5819 run_test 46 "dirtying a previously written page ================"
5820
5821 # test_47 is removed "Device nodes check" is moved to test_28
5822
5823 test_48a() { # bug 2399
5824         [ "$mds1_FSTYPE" = "zfs" ] &&
5825         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5826                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5827
5828         test_mkdir $DIR/$tdir
5829         cd $DIR/$tdir
5830         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5831         test_mkdir $DIR/$tdir
5832         touch foo || error "'touch foo' failed after recreating cwd"
5833         test_mkdir bar
5834         touch .foo || error "'touch .foo' failed after recreating cwd"
5835         test_mkdir .bar
5836         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5837         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5838         cd . || error "'cd .' failed after recreating cwd"
5839         mkdir . && error "'mkdir .' worked after recreating cwd"
5840         rmdir . && error "'rmdir .' worked after recreating cwd"
5841         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5842         cd .. || error "'cd ..' failed after recreating cwd"
5843 }
5844 run_test 48a "Access renamed working dir (should return errors)="
5845
5846 test_48b() { # bug 2399
5847         rm -rf $DIR/$tdir
5848         test_mkdir $DIR/$tdir
5849         cd $DIR/$tdir
5850         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5851         touch foo && error "'touch foo' worked after removing cwd"
5852         mkdir foo && error "'mkdir foo' worked after removing cwd"
5853         touch .foo && error "'touch .foo' worked after removing cwd"
5854         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5855         ls . > /dev/null && error "'ls .' worked after removing cwd"
5856         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5857         mkdir . && error "'mkdir .' worked after removing cwd"
5858         rmdir . && error "'rmdir .' worked after removing cwd"
5859         ln -s . foo && error "'ln -s .' worked after removing cwd"
5860         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5861 }
5862 run_test 48b "Access removed working dir (should return errors)="
5863
5864 test_48c() { # bug 2350
5865         #lctl set_param debug=-1
5866         #set -vx
5867         rm -rf $DIR/$tdir
5868         test_mkdir -p $DIR/$tdir/dir
5869         cd $DIR/$tdir/dir
5870         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5871         $TRACE touch foo && error "touch foo worked after removing cwd"
5872         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5873         touch .foo && error "touch .foo worked after removing cwd"
5874         mkdir .foo && error "mkdir .foo worked after removing cwd"
5875         $TRACE ls . && error "'ls .' worked after removing cwd"
5876         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5877         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5878         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5879         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5880         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5881 }
5882 run_test 48c "Access removed working subdir (should return errors)"
5883
5884 test_48d() { # bug 2350
5885         #lctl set_param debug=-1
5886         #set -vx
5887         rm -rf $DIR/$tdir
5888         test_mkdir -p $DIR/$tdir/dir
5889         cd $DIR/$tdir/dir
5890         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5891         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5892         $TRACE touch foo && error "'touch foo' worked after removing parent"
5893         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5894         touch .foo && error "'touch .foo' worked after removing parent"
5895         mkdir .foo && error "mkdir .foo worked after removing parent"
5896         $TRACE ls . && error "'ls .' worked after removing parent"
5897         $TRACE ls .. && error "'ls ..' worked after removing parent"
5898         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5899         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5900         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5901         true
5902 }
5903 run_test 48d "Access removed parent subdir (should return errors)"
5904
5905 test_48e() { # bug 4134
5906         #lctl set_param debug=-1
5907         #set -vx
5908         rm -rf $DIR/$tdir
5909         test_mkdir -p $DIR/$tdir/dir
5910         cd $DIR/$tdir/dir
5911         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5912         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5913         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5914         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5915         # On a buggy kernel addition of "touch foo" after cd .. will
5916         # produce kernel oops in lookup_hash_it
5917         touch ../foo && error "'cd ..' worked after recreate parent"
5918         cd $DIR
5919         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5920 }
5921 run_test 48e "Access to recreated parent subdir (should return errors)"
5922
5923 test_48f() {
5924         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5925                 skip "need MDS >= 2.13.55"
5926         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5927         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5928                 skip "needs different host for mdt1 mdt2"
5929         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5930
5931         $LFS mkdir -i0 $DIR/$tdir
5932         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5933
5934         for d in sub1 sub2 sub3; do
5935                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5936                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5937                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5938         done
5939
5940         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5941 }
5942 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5943
5944 test_49() { # LU-1030
5945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5946         remote_ost_nodsh && skip "remote OST with nodsh"
5947
5948         # get ost1 size - $FSNAME-OST0000
5949         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5950                 awk '{ print $4 }')
5951         # write 800M at maximum
5952         [[ $ost1_size -lt 2 ]] && ost1_size=2
5953         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5954
5955         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5956         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5957         local dd_pid=$!
5958
5959         # change max_pages_per_rpc while writing the file
5960         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5961         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5962         # loop until dd process exits
5963         while ps ax -opid | grep -wq $dd_pid; do
5964                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5965                 sleep $((RANDOM % 5 + 1))
5966         done
5967         # restore original max_pages_per_rpc
5968         $LCTL set_param $osc1_mppc=$orig_mppc
5969         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5970 }
5971 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5972
5973 test_50() {
5974         # bug 1485
5975         test_mkdir $DIR/$tdir
5976         cd $DIR/$tdir
5977         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5978 }
5979 run_test 50 "special situations: /proc symlinks  ==============="
5980
5981 test_51a() {    # was test_51
5982         # bug 1516 - create an empty entry right after ".." then split dir
5983         test_mkdir -c1 $DIR/$tdir
5984         touch $DIR/$tdir/foo
5985         $MCREATE $DIR/$tdir/bar
5986         rm $DIR/$tdir/foo
5987         createmany -m $DIR/$tdir/longfile 201
5988         FNUM=202
5989         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5990                 $MCREATE $DIR/$tdir/longfile$FNUM
5991                 FNUM=$(($FNUM + 1))
5992                 echo -n "+"
5993         done
5994         echo
5995         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5996 }
5997 run_test 51a "special situations: split htree with empty entry =="
5998
5999 cleanup_print_lfs_df () {
6000         trap 0
6001         $LFS df
6002         $LFS df -i
6003 }
6004
6005 test_51b() {
6006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6007
6008         local dir=$DIR/$tdir
6009         local nrdirs=$((65536 + 100))
6010
6011         # cleanup the directory
6012         rm -fr $dir
6013
6014         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6015
6016         $LFS df
6017         $LFS df -i
6018         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6019         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6020         [[ $numfree -lt $nrdirs ]] &&
6021                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6022
6023         # need to check free space for the directories as well
6024         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6025         numfree=$(( blkfree / $(fs_inode_ksize) ))
6026         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6027
6028         trap cleanup_print_lfs_df EXIT
6029
6030         # create files
6031         createmany -d $dir/d $nrdirs || {
6032                 unlinkmany $dir/d $nrdirs
6033                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6034         }
6035
6036         # really created :
6037         nrdirs=$(ls -U $dir | wc -l)
6038
6039         # unlink all but 100 subdirectories, then check it still works
6040         local left=100
6041         local delete=$((nrdirs - left))
6042
6043         $LFS df
6044         $LFS df -i
6045
6046         # for ldiskfs the nlink count should be 1, but this is OSD specific
6047         # and so this is listed for informational purposes only
6048         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6049         unlinkmany -d $dir/d $delete ||
6050                 error "unlink of first $delete subdirs failed"
6051
6052         echo "nlink between: $(stat -c %h $dir)"
6053         local found=$(ls -U $dir | wc -l)
6054         [ $found -ne $left ] &&
6055                 error "can't find subdirs: found only $found, expected $left"
6056
6057         unlinkmany -d $dir/d $delete $left ||
6058                 error "unlink of second $left subdirs failed"
6059         # regardless of whether the backing filesystem tracks nlink accurately
6060         # or not, the nlink count shouldn't be more than "." and ".." here
6061         local after=$(stat -c %h $dir)
6062         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6063                 echo "nlink after: $after"
6064
6065         cleanup_print_lfs_df
6066 }
6067 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6068
6069 test_51d_sub() {
6070         local stripecount=$1
6071         local nfiles=$2
6072
6073         log "create files with stripecount=$stripecount"
6074         $LFS setstripe -C $stripecount $DIR/$tdir
6075         createmany -o $DIR/$tdir/t- $nfiles
6076         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6077         for ((n = 0; n < $OSTCOUNT; n++)); do
6078                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6079                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6080                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6081                             '($1 == '$n') { objs += 1 } \
6082                             END { printf("%0.0f", objs) }')
6083                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6084         done
6085         unlinkmany $DIR/$tdir/t- $nfiles
6086         rm  -f $TMP/$tfile
6087
6088         local nlast
6089         local min=4
6090         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6091
6092         # For some combinations of stripecount and OSTCOUNT current code
6093         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6094         # than others. Rather than skipping this test entirely, check that
6095         # and keep testing to ensure imbalance does not get worse. LU-15282
6096         (( (OSTCOUNT == 6 && stripecount == 4) ||
6097            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6098            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6099         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6100                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6101                         { $LFS df && $LFS df -i &&
6102                         error "stripecount=$stripecount: " \
6103                               "OST $n has fewer objects vs. OST $nlast " \
6104                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6105                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6106                         { $LFS df && $LFS df -i &&
6107                         error "stripecount=$stripecount: " \
6108                               "OST $n has more objects vs. OST $nlast " \
6109                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6110
6111                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6112                         { $LFS df && $LFS df -i &&
6113                         error "stripecount=$stripecount: " \
6114                               "OST $n has fewer #0 objects vs. OST $nlast " \
6115                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6116                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6117                         { $LFS df && $LFS df -i &&
6118                         error "stripecount=$stripecount: " \
6119                               "OST $n has more #0 objects vs. OST $nlast " \
6120                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6121         done
6122 }
6123
6124 test_51d() {
6125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6126         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6127
6128         local stripecount
6129         local per_ost=100
6130         local nfiles=$((per_ost * OSTCOUNT))
6131         local mdts=$(comma_list $(mdts_nodes))
6132         local param="osp.*.create_count"
6133         local qos_old=$(do_facet mds1 \
6134                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6135
6136         do_nodes $mdts \
6137                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6138         stack_trap "do_nodes $mdts \
6139                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6140
6141         test_mkdir $DIR/$tdir
6142         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6143         (( dirstripes > 0 )) || dirstripes=1
6144
6145         # Ensure enough OST objects precreated for tests to pass without
6146         # running out of objects.  This is an LOV r-r OST algorithm test,
6147         # not an OST object precreation test.
6148         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6149         (( old >= nfiles )) ||
6150         {
6151                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6152
6153                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6154                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6155
6156                 # trigger precreation from all MDTs for all OSTs
6157                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6158                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6159                 done
6160         }
6161
6162         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6163                 sleep 8  # allow object precreation to catch up
6164                 test_51d_sub $stripecount $nfiles
6165         done
6166 }
6167 run_test 51d "check LOV round-robin OST object distribution"
6168
6169 test_51e() {
6170         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6171                 skip_env "ldiskfs only test"
6172         fi
6173
6174         test_mkdir -c1 $DIR/$tdir
6175         test_mkdir -c1 $DIR/$tdir/d0
6176
6177         touch $DIR/$tdir/d0/foo
6178         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6179                 error "file exceed 65000 nlink limit!"
6180         unlinkmany $DIR/$tdir/d0/f- 65001
6181         return 0
6182 }
6183 run_test 51e "check file nlink limit"
6184
6185 test_51f() {
6186         test_mkdir $DIR/$tdir
6187
6188         local max=100000
6189         local ulimit_old=$(ulimit -n)
6190         local spare=20 # number of spare fd's for scripts/libraries, etc.
6191         local mdt=$($LFS getstripe -m $DIR/$tdir)
6192         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6193
6194         echo "MDT$mdt numfree=$numfree, max=$max"
6195         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6196         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6197                 while ! ulimit -n $((numfree + spare)); do
6198                         numfree=$((numfree * 3 / 4))
6199                 done
6200                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6201         else
6202                 echo "left ulimit at $ulimit_old"
6203         fi
6204
6205         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6206                 unlinkmany $DIR/$tdir/f $numfree
6207                 error "create+open $numfree files in $DIR/$tdir failed"
6208         }
6209         ulimit -n $ulimit_old
6210
6211         # if createmany exits at 120s there will be fewer than $numfree files
6212         unlinkmany $DIR/$tdir/f $numfree || true
6213 }
6214 run_test 51f "check many open files limit"
6215
6216 test_52a() {
6217         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6218         test_mkdir $DIR/$tdir
6219         touch $DIR/$tdir/foo
6220         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6221         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6222         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6223         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6224         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6225                                         error "link worked"
6226         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6227         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6228         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6229                                                      error "lsattr"
6230         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6231         cp -r $DIR/$tdir $TMP/
6232         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6233 }
6234 run_test 52a "append-only flag test (should return errors)"
6235
6236 test_52b() {
6237         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6238         test_mkdir $DIR/$tdir
6239         touch $DIR/$tdir/foo
6240         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6241         cat test > $DIR/$tdir/foo && error "cat test worked"
6242         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6243         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6244         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6245                                         error "link worked"
6246         echo foo >> $DIR/$tdir/foo && error "echo worked"
6247         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6248         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6249         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6250         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6251                                                         error "lsattr"
6252         chattr -i $DIR/$tdir/foo || error "chattr failed"
6253
6254         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6255 }
6256 run_test 52b "immutable flag test (should return errors) ======="
6257
6258 test_53() {
6259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6260         remote_mds_nodsh && skip "remote MDS with nodsh"
6261         remote_ost_nodsh && skip "remote OST with nodsh"
6262
6263         local param
6264         local param_seq
6265         local ostname
6266         local mds_last
6267         local mds_last_seq
6268         local ost_last
6269         local ost_last_seq
6270         local ost_last_id
6271         local ostnum
6272         local node
6273         local found=false
6274         local support_last_seq=true
6275
6276         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6277                 support_last_seq=false
6278
6279         # only test MDT0000
6280         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6281         local value
6282         for value in $(do_facet $SINGLEMDS \
6283                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6284                 param=$(echo ${value[0]} | cut -d "=" -f1)
6285                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6286
6287                 if $support_last_seq; then
6288                         param_seq=$(echo $param |
6289                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6290                         mds_last_seq=$(do_facet $SINGLEMDS \
6291                                        $LCTL get_param -n $param_seq)
6292                 fi
6293                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6294
6295                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6296                 node=$(facet_active_host ost$((ostnum+1)))
6297                 param="obdfilter.$ostname.last_id"
6298                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6299                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6300                         ost_last_id=$ost_last
6301
6302                         if $support_last_seq; then
6303                                 ost_last_id=$(echo $ost_last |
6304                                               awk -F':' '{print $2}' |
6305                                               sed -e "s/^0x//g")
6306                                 ost_last_seq=$(echo $ost_last |
6307                                                awk -F':' '{print $1}')
6308                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6309                         fi
6310
6311                         if [[ $ost_last_id != $mds_last ]]; then
6312                                 error "$ost_last_id != $mds_last"
6313                         else
6314                                 found=true
6315                                 break
6316                         fi
6317                 done
6318         done
6319         $found || error "can not match last_seq/last_id for $mdtosc"
6320         return 0
6321 }
6322 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6323
6324 test_54a() {
6325         $SOCKETSERVER $DIR/socket ||
6326                 error "$SOCKETSERVER $DIR/socket failed: $?"
6327         $SOCKETCLIENT $DIR/socket ||
6328                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6329         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6330 }
6331 run_test 54a "unix domain socket test"
6332
6333 test_54b() {
6334         f="$DIR/f54b"
6335         mknod $f c 1 3
6336         chmod 0666 $f
6337         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6338 }
6339 run_test 54b "char device works in lustre ======================"
6340
6341 find_loop_dev() {
6342         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6343         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6344         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6345
6346         for i in $(seq 3 7); do
6347                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6348                 LOOPDEV=$LOOPBASE$i
6349                 LOOPNUM=$i
6350                 break
6351         done
6352 }
6353
6354 cleanup_54c() {
6355         local rc=0
6356         loopdev="$DIR/loop54c"
6357
6358         trap 0
6359         $UMOUNT $DIR/$tdir || rc=$?
6360         losetup -d $loopdev || true
6361         losetup -d $LOOPDEV || true
6362         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6363         return $rc
6364 }
6365
6366 test_54c() {
6367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6368
6369         loopdev="$DIR/loop54c"
6370
6371         find_loop_dev
6372         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6373         trap cleanup_54c EXIT
6374         mknod $loopdev b 7 $LOOPNUM
6375         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6376         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6377         losetup $loopdev $DIR/$tfile ||
6378                 error "can't set up $loopdev for $DIR/$tfile"
6379         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6380         test_mkdir $DIR/$tdir
6381         mount -t ext2 $loopdev $DIR/$tdir ||
6382                 error "error mounting $loopdev on $DIR/$tdir"
6383         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6384                 error "dd write"
6385         df $DIR/$tdir
6386         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6387                 error "dd read"
6388         cleanup_54c
6389 }
6390 run_test 54c "block device works in lustre ====================="
6391
6392 test_54d() {
6393         local pipe="$DIR/$tfile.pipe"
6394         local string="aaaaaa"
6395
6396         mknod $pipe p
6397         echo -n "$string" > $pipe &
6398         local result=$(cat $pipe)
6399         [[ "$result" == "$string" ]] || error "$result != $string"
6400 }
6401 run_test 54d "fifo device works in lustre ======================"
6402
6403 test_54e() {
6404         f="$DIR/f54e"
6405         string="aaaaaa"
6406         cp -aL /dev/console $f
6407         echo $string > $f || error "echo $string to $f failed"
6408 }
6409 run_test 54e "console/tty device works in lustre ======================"
6410
6411 test_55a() {
6412         local dev_path="/sys/kernel/debug/lustre/devices"
6413
6414         load_module kunit/obd_test verbose=2 || error "load_module failed"
6415
6416         # This must be run in iteractive mode, since attach and setup
6417         # are stateful
6418         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6419                 attach obd_test obd_name obd_uuid
6420                 setup obd_test
6421         EOF"
6422
6423         echo "Devices:"
6424         cat "$dev_path" | tail -n 10
6425
6426         $LCTL --device "obd_name" cleanup
6427         $LCTL --device "obd_name" detach
6428
6429         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6430                 error "OBD unit test failed"
6431
6432         rmmod -v obd_test ||
6433                 error "rmmod failed (may trigger a failure in a later test)"
6434 }
6435 run_test 55a "OBD device life cycle unit tests"
6436
6437 test_55b() {
6438         local dev_path="/sys/kernel/debug/lustre/devices"
6439         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6440
6441         # Set up a large number of devices, using the number
6442         # that can be set up in about a minute (based on prior
6443         # testing). We don't want to run this test forever.
6444         local num_dev_to_create="$(( 24000 - $dev_count))"
6445
6446         load_module kunit/obd_test || error "load_module failed"
6447
6448         local start=$SECONDS
6449
6450         # This must be run in iteractive mode, since attach and setup
6451         # are stateful
6452         for ((i = 1; i <= num_dev_to_create; i++)); do
6453                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6454                 echo "setup obd_test_$i"
6455         done | $LCTL || error "OBD device creation failed"
6456
6457         echo "Load time: $((SECONDS - start))"
6458         echo "Devices:"
6459         cat "$dev_path" | tail -n 10
6460
6461         for ((i = 1; i <= num_dev_to_create; i++)); do
6462                 echo "--device obd_name_$i cleanup"
6463                 echo "--device obd_name_$i detach"
6464         done | $LCTL || error "OBD device cleanup failed"
6465
6466         echo "Unload time: $((SECONDS - start))"
6467
6468         rmmod -v obd_test ||
6469                 error "rmmod failed (may trigger a failure in a later test)"
6470 }
6471 run_test 55b "Load and unload max OBD devices"
6472
6473 test_56a() {
6474         local numfiles=3
6475         local numdirs=2
6476         local dir=$DIR/$tdir
6477
6478         rm -rf $dir
6479         test_mkdir -p $dir/dir
6480         for i in $(seq $numfiles); do
6481                 touch $dir/file$i
6482                 touch $dir/dir/file$i
6483         done
6484
6485         local numcomp=$($LFS getstripe --component-count $dir)
6486
6487         [[ $numcomp == 0 ]] && numcomp=1
6488
6489         # test lfs getstripe with --recursive
6490         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6491
6492         [[ $filenum -eq $((numfiles * 2)) ]] ||
6493                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6494         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6495         [[ $filenum -eq $numfiles ]] ||
6496                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6497         echo "$LFS getstripe showed obdidx or l_ost_idx"
6498
6499         # test lfs getstripe with file instead of dir
6500         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6501         [[ $filenum -eq 1 ]] ||
6502                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6503         echo "$LFS getstripe file1 passed"
6504
6505         #test lfs getstripe with --verbose
6506         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6507         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6508                 error "$LFS getstripe --verbose $dir: "\
6509                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6510         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6511                 error "$LFS getstripe $dir: showed lmm_magic"
6512
6513         #test lfs getstripe with -v prints lmm_fid
6514         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6515         local countfids=$(((numdirs + numfiles) * numcomp))
6516         [[ $filenum -eq $countfids ]] ||
6517                 error "$LFS getstripe -v $dir: "\
6518                       "got $filenum want $countfids lmm_fid"
6519         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6520                 error "$LFS getstripe $dir: showed lmm_fid by default"
6521         echo "$LFS getstripe --verbose passed"
6522
6523         #check for FID information
6524         local fid1=$($LFS getstripe --fid $dir/file1)
6525         local fid2=$($LFS getstripe --verbose $dir/file1 |
6526                      awk '/lmm_fid: / { print $2; exit; }')
6527         local fid3=$($LFS path2fid $dir/file1)
6528
6529         [ "$fid1" != "$fid2" ] &&
6530                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6531         [ "$fid1" != "$fid3" ] &&
6532                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6533         echo "$LFS getstripe --fid passed"
6534
6535         #test lfs getstripe with --obd
6536         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6537                 error "$LFS getstripe --obd wrong_uuid: should return error"
6538
6539         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6540
6541         local ostidx=1
6542         local obduuid=$(ostuuid_from_index $ostidx)
6543         local found=$($LFS getstripe -r --obd $obduuid $dir |
6544                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6545
6546         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6547         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6548                 ((filenum--))
6549         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6550                 ((filenum--))
6551
6552         [[ $found -eq $filenum ]] ||
6553                 error "$LFS getstripe --obd: found $found expect $filenum"
6554         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6555                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6556                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6557                 error "$LFS getstripe --obd: should not show file on other obd"
6558         echo "$LFS getstripe --obd passed"
6559 }
6560 run_test 56a "check $LFS getstripe"
6561
6562 test_56b() {
6563         local dir=$DIR/$tdir
6564         local numdirs=3
6565
6566         test_mkdir $dir
6567         for i in $(seq $numdirs); do
6568                 test_mkdir $dir/dir$i
6569         done
6570
6571         # test lfs getdirstripe default mode is non-recursion, which is
6572         # different from lfs getstripe
6573         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6574
6575         [[ $dircnt -eq 1 ]] ||
6576                 error "$LFS getdirstripe: found $dircnt, not 1"
6577         dircnt=$($LFS getdirstripe --recursive $dir |
6578                 grep -c lmv_stripe_count)
6579         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6580                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6581 }
6582 run_test 56b "check $LFS getdirstripe"
6583
6584 test_56bb() {
6585         verify_yaml_available || skip_env "YAML verification not installed"
6586         local output_file=$DIR/$tfile.out
6587
6588         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6589
6590         cat $output_file
6591         cat $output_file | verify_yaml || error "layout is not valid YAML"
6592 }
6593 run_test 56bb "check $LFS getdirstripe layout is YAML"
6594
6595 test_56c() {
6596         remote_ost_nodsh && skip "remote OST with nodsh"
6597
6598         local ost_idx=0
6599         local ost_name=$(ostname_from_index $ost_idx)
6600         local old_status=$(ost_dev_status $ost_idx)
6601         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6602
6603         [[ -z "$old_status" ]] ||
6604                 skip_env "OST $ost_name is in $old_status status"
6605
6606         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6607         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6608                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6609         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6610                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6611                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6612         fi
6613
6614         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6615                 error "$LFS df -v showing inactive devices"
6616         sleep_maxage
6617
6618         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6619
6620         [[ "$new_status" =~ "D" ]] ||
6621                 error "$ost_name status is '$new_status', missing 'D'"
6622         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6623                 [[ "$new_status" =~ "N" ]] ||
6624                         error "$ost_name status is '$new_status', missing 'N'"
6625         fi
6626         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6627                 [[ "$new_status" =~ "f" ]] ||
6628                         error "$ost_name status is '$new_status', missing 'f'"
6629         fi
6630
6631         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6632         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6633                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6634         [[ -z "$p" ]] && restore_lustre_params < $p || true
6635         sleep_maxage
6636
6637         new_status=$(ost_dev_status $ost_idx)
6638         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6639                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6640         # can't check 'f' as devices may actually be on flash
6641 }
6642 run_test 56c "check 'lfs df' showing device status"
6643
6644 test_56d() {
6645         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6646         local osts=$($LFS df -v $MOUNT | grep -c OST)
6647
6648         $LFS df $MOUNT
6649
6650         (( mdts == MDSCOUNT )) ||
6651                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6652         (( osts == OSTCOUNT )) ||
6653                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6654 }
6655 run_test 56d "'lfs df -v' prints only configured devices"
6656
6657 test_56e() {
6658         err_enoent=2 # No such file or directory
6659         err_eopnotsupp=95 # Operation not supported
6660
6661         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6662         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6663
6664         # Check for handling of path not exists
6665         output=$($LFS df $enoent_mnt 2>&1)
6666         ret=$?
6667
6668         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6669         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6670                 error "expect failure $err_enoent, not $ret"
6671
6672         # Check for handling of non-Lustre FS
6673         output=$($LFS df $notsup_mnt)
6674         ret=$?
6675
6676         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6677         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6678                 error "expect success $err_eopnotsupp, not $ret"
6679
6680         # Check for multiple LustreFS argument
6681         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6682         ret=$?
6683
6684         [[ $output -eq 3 && $ret -eq 0 ]] ||
6685                 error "expect success 3, not $output, rc = $ret"
6686
6687         # Check for correct non-Lustre FS handling among multiple
6688         # LustreFS argument
6689         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6690                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6691         ret=$?
6692
6693         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6694                 error "expect success 2, not $output, rc = $ret"
6695 }
6696 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6697
6698 NUMFILES=3
6699 NUMDIRS=3
6700 setup_56() {
6701         local local_tdir="$1"
6702         local local_numfiles="$2"
6703         local local_numdirs="$3"
6704         local dir_params="$4"
6705         local dir_stripe_params="$5"
6706
6707         if [ ! -d "$local_tdir" ] ; then
6708                 test_mkdir -p $dir_stripe_params $local_tdir
6709                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6710                 for i in $(seq $local_numfiles) ; do
6711                         touch $local_tdir/file$i
6712                 done
6713                 for i in $(seq $local_numdirs) ; do
6714                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6715                         for j in $(seq $local_numfiles) ; do
6716                                 touch $local_tdir/dir$i/file$j
6717                         done
6718                 done
6719         fi
6720 }
6721
6722 setup_56_special() {
6723         local local_tdir=$1
6724         local local_numfiles=$2
6725         local local_numdirs=$3
6726
6727         setup_56 $local_tdir $local_numfiles $local_numdirs
6728
6729         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6730                 for i in $(seq $local_numfiles) ; do
6731                         mknod $local_tdir/loop${i}b b 7 $i
6732                         mknod $local_tdir/null${i}c c 1 3
6733                         ln -s $local_tdir/file1 $local_tdir/link${i}
6734                 done
6735                 for i in $(seq $local_numdirs) ; do
6736                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6737                         mknod $local_tdir/dir$i/null${i}c c 1 3
6738                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6739                 done
6740         fi
6741 }
6742
6743 test_56g() {
6744         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6745         local expected=$(($NUMDIRS + 2))
6746
6747         setup_56 $dir $NUMFILES $NUMDIRS
6748
6749         # test lfs find with -name
6750         for i in $(seq $NUMFILES) ; do
6751                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6752
6753                 [ $nums -eq $expected ] ||
6754                         error "lfs find -name '*$i' $dir wrong: "\
6755                               "found $nums, expected $expected"
6756         done
6757 }
6758 run_test 56g "check lfs find -name"
6759
6760 test_56h() {
6761         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6762         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6763
6764         setup_56 $dir $NUMFILES $NUMDIRS
6765
6766         # test lfs find with ! -name
6767         for i in $(seq $NUMFILES) ; do
6768                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6769
6770                 [ $nums -eq $expected ] ||
6771                         error "lfs find ! -name '*$i' $dir wrong: "\
6772                               "found $nums, expected $expected"
6773         done
6774 }
6775 run_test 56h "check lfs find ! -name"
6776
6777 test_56i() {
6778         local dir=$DIR/$tdir
6779
6780         test_mkdir $dir
6781
6782         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6783         local out=$($cmd)
6784
6785         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6786 }
6787 run_test 56i "check 'lfs find -ost UUID' skips directories"
6788
6789 test_56j() {
6790         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6791
6792         setup_56_special $dir $NUMFILES $NUMDIRS
6793
6794         local expected=$((NUMDIRS + 1))
6795         local cmd="$LFS find -type d $dir"
6796         local nums=$($cmd | wc -l)
6797
6798         [ $nums -eq $expected ] ||
6799                 error "'$cmd' wrong: found $nums, expected $expected"
6800 }
6801 run_test 56j "check lfs find -type d"
6802
6803 test_56k() {
6804         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6805
6806         setup_56_special $dir $NUMFILES $NUMDIRS
6807
6808         local expected=$(((NUMDIRS + 1) * NUMFILES))
6809         local cmd="$LFS find -type f $dir"
6810         local nums=$($cmd | wc -l)
6811
6812         [ $nums -eq $expected ] ||
6813                 error "'$cmd' wrong: found $nums, expected $expected"
6814 }
6815 run_test 56k "check lfs find -type f"
6816
6817 test_56l() {
6818         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6819
6820         setup_56_special $dir $NUMFILES $NUMDIRS
6821
6822         local expected=$((NUMDIRS + NUMFILES))
6823         local cmd="$LFS find -type b $dir"
6824         local nums=$($cmd | wc -l)
6825
6826         [ $nums -eq $expected ] ||
6827                 error "'$cmd' wrong: found $nums, expected $expected"
6828 }
6829 run_test 56l "check lfs find -type b"
6830
6831 test_56m() {
6832         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6833
6834         setup_56_special $dir $NUMFILES $NUMDIRS
6835
6836         local expected=$((NUMDIRS + NUMFILES))
6837         local cmd="$LFS find -type c $dir"
6838         local nums=$($cmd | wc -l)
6839         [ $nums -eq $expected ] ||
6840                 error "'$cmd' wrong: found $nums, expected $expected"
6841 }
6842 run_test 56m "check lfs find -type c"
6843
6844 test_56n() {
6845         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6846         setup_56_special $dir $NUMFILES $NUMDIRS
6847
6848         local expected=$((NUMDIRS + NUMFILES))
6849         local cmd="$LFS find -type l $dir"
6850         local nums=$($cmd | wc -l)
6851
6852         [ $nums -eq $expected ] ||
6853                 error "'$cmd' wrong: found $nums, expected $expected"
6854 }
6855 run_test 56n "check lfs find -type l"
6856
6857 test_56o() {
6858         local dir=$DIR/$tdir
6859
6860         setup_56 $dir $NUMFILES $NUMDIRS
6861         utime $dir/file1 > /dev/null || error "utime (1)"
6862         utime $dir/file2 > /dev/null || error "utime (2)"
6863         utime $dir/dir1 > /dev/null || error "utime (3)"
6864         utime $dir/dir2 > /dev/null || error "utime (4)"
6865         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6866         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6867
6868         local expected=4
6869         local nums=$($LFS find -mtime +0 $dir | wc -l)
6870
6871         [ $nums -eq $expected ] ||
6872                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6873
6874         expected=12
6875         cmd="$LFS find -mtime 0 $dir"
6876         nums=$($cmd | wc -l)
6877         [ $nums -eq $expected ] ||
6878                 error "'$cmd' wrong: found $nums, expected $expected"
6879 }
6880 run_test 56o "check lfs find -mtime for old files"
6881
6882 test_56ob() {
6883         local dir=$DIR/$tdir
6884         local expected=1
6885         local count=0
6886
6887         # just to make sure there is something that won't be found
6888         test_mkdir $dir
6889         touch $dir/$tfile.now
6890
6891         for age in year week day hour min; do
6892                 count=$((count + 1))
6893
6894                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6895                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6896                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6897
6898                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6899                 local nums=$($cmd | wc -l)
6900                 [ $nums -eq $expected ] ||
6901                         error "'$cmd' wrong: found $nums, expected $expected"
6902
6903                 cmd="$LFS find $dir -atime $count${age:0:1}"
6904                 nums=$($cmd | wc -l)
6905                 [ $nums -eq $expected ] ||
6906                         error "'$cmd' wrong: found $nums, expected $expected"
6907         done
6908
6909         sleep 2
6910         cmd="$LFS find $dir -ctime +1s -type f"
6911         nums=$($cmd | wc -l)
6912         (( $nums == $count * 2 + 1)) ||
6913                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6914 }
6915 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6916
6917 test_newerXY_base() {
6918         local x=$1
6919         local y=$2
6920         local dir=$DIR/$tdir
6921         local ref
6922         local negref
6923
6924         if [ $y == "t" ]; then
6925                 if [ $x == "b" ]; then
6926                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6927                 else
6928                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6929                 fi
6930         else
6931                 ref=$DIR/$tfile.newer.$x$y
6932                 touch $ref || error "touch $ref failed"
6933         fi
6934
6935         echo "before = $ref"
6936         sleep 2
6937         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6938         sleep 2
6939         if [ $y == "t" ]; then
6940                 if [ $x == "b" ]; then
6941                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6942                 else
6943                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6944                 fi
6945         else
6946                 negref=$DIR/$tfile.negnewer.$x$y
6947                 touch $negref || error "touch $negref failed"
6948         fi
6949
6950         echo "after = $negref"
6951         local cmd="$LFS find $dir -newer$x$y $ref"
6952         local nums=$(eval $cmd | wc -l)
6953         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6954
6955         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6956                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6957
6958         cmd="$LFS find $dir ! -newer$x$y $negref"
6959         nums=$(eval $cmd | wc -l)
6960         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6961                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6962
6963         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6964         nums=$(eval $cmd | wc -l)
6965         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6966                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6967
6968         rm -rf $DIR/*
6969 }
6970
6971 test_56oc() {
6972         test_newerXY_base "a" "a"
6973         test_newerXY_base "a" "m"
6974         test_newerXY_base "a" "c"
6975         test_newerXY_base "m" "a"
6976         test_newerXY_base "m" "m"
6977         test_newerXY_base "m" "c"
6978         test_newerXY_base "c" "a"
6979         test_newerXY_base "c" "m"
6980         test_newerXY_base "c" "c"
6981
6982         test_newerXY_base "a" "t"
6983         test_newerXY_base "m" "t"
6984         test_newerXY_base "c" "t"
6985
6986         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6987            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6988                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6989
6990         test_newerXY_base "b" "b"
6991         test_newerXY_base "b" "t"
6992 }
6993 run_test 56oc "check lfs find -newerXY work"
6994
6995 test_56od() {
6996         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6997                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6998
6999         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7000                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7001
7002         local dir=$DIR/$tdir
7003         local ref=$DIR/$tfile.ref
7004         local negref=$DIR/$tfile.negref
7005
7006         mkdir $dir || error "mkdir $dir failed"
7007         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7008         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7009         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7010         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7011         touch $ref || error "touch $ref failed"
7012         # sleep 3 seconds at least
7013         sleep 3
7014
7015         local before=$(do_facet mds1 date +%s)
7016         local skew=$(($(date +%s) - before + 1))
7017
7018         if (( skew < 0 && skew > -5 )); then
7019                 sleep $((0 - skew + 1))
7020                 skew=0
7021         fi
7022
7023         # Set the dir stripe params to limit files all on MDT0,
7024         # otherwise we need to calc the max clock skew between
7025         # the client and MDTs.
7026         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7027         sleep 2
7028         touch $negref || error "touch $negref failed"
7029
7030         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7031         local nums=$($cmd | wc -l)
7032         local expected=$(((NUMFILES + 1) * NUMDIRS))
7033
7034         [ $nums -eq $expected ] ||
7035                 error "'$cmd' wrong: found $nums, expected $expected"
7036
7037         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7038         nums=$($cmd | wc -l)
7039         expected=$((NUMFILES + 1))
7040         [ $nums -eq $expected ] ||
7041                 error "'$cmd' wrong: found $nums, expected $expected"
7042
7043         [ $skew -lt 0 ] && return
7044
7045         local after=$(do_facet mds1 date +%s)
7046         local age=$((after - before + 1 + skew))
7047
7048         cmd="$LFS find $dir -btime -${age}s -type f"
7049         nums=$($cmd | wc -l)
7050         expected=$(((NUMFILES + 1) * NUMDIRS))
7051
7052         echo "Clock skew between client and server: $skew, age:$age"
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055
7056         expected=$(($NUMDIRS + 1))
7057         cmd="$LFS find $dir -btime -${age}s -type d"
7058         nums=$($cmd | wc -l)
7059         [ $nums -eq $expected ] ||
7060                 error "'$cmd' wrong: found $nums, expected $expected"
7061         rm -f $ref $negref || error "Failed to remove $ref $negref"
7062 }
7063 run_test 56od "check lfs find -btime with units"
7064
7065 test_56p() {
7066         [ $RUNAS_ID -eq $UID ] &&
7067                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7068
7069         local dir=$DIR/$tdir
7070
7071         setup_56 $dir $NUMFILES $NUMDIRS
7072         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7073
7074         local expected=$NUMFILES
7075         local cmd="$LFS find -uid $RUNAS_ID $dir"
7076         local nums=$($cmd | wc -l)
7077
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080
7081         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7082         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7083         nums=$($cmd | wc -l)
7084         [ $nums -eq $expected ] ||
7085                 error "'$cmd' wrong: found $nums, expected $expected"
7086 }
7087 run_test 56p "check lfs find -uid and ! -uid"
7088
7089 test_56q() {
7090         [ $RUNAS_ID -eq $UID ] &&
7091                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7092
7093         local dir=$DIR/$tdir
7094
7095         setup_56 $dir $NUMFILES $NUMDIRS
7096         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7097
7098         local expected=$NUMFILES
7099         local cmd="$LFS find -gid $RUNAS_GID $dir"
7100         local nums=$($cmd | wc -l)
7101
7102         [ $nums -eq $expected ] ||
7103                 error "'$cmd' wrong: found $nums, expected $expected"
7104
7105         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7106         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7107         nums=$($cmd | wc -l)
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110 }
7111 run_test 56q "check lfs find -gid and ! -gid"
7112
7113 test_56r() {
7114         local dir=$DIR/$tdir
7115
7116         setup_56 $dir $NUMFILES $NUMDIRS
7117
7118         local expected=12
7119         local cmd="$LFS find -size 0 -type f -lazy $dir"
7120         local nums=$($cmd | wc -l)
7121
7122         [ $nums -eq $expected ] ||
7123                 error "'$cmd' wrong: found $nums, expected $expected"
7124         cmd="$LFS find -size 0 -type f $dir"
7125         nums=$($cmd | wc -l)
7126         [ $nums -eq $expected ] ||
7127                 error "'$cmd' wrong: found $nums, expected $expected"
7128
7129         expected=0
7130         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7131         nums=$($cmd | wc -l)
7132         [ $nums -eq $expected ] ||
7133                 error "'$cmd' wrong: found $nums, expected $expected"
7134         cmd="$LFS find ! -size 0 -type f $dir"
7135         nums=$($cmd | wc -l)
7136         [ $nums -eq $expected ] ||
7137                 error "'$cmd' wrong: found $nums, expected $expected"
7138
7139         echo "test" > $dir/$tfile
7140         echo "test2" > $dir/$tfile.2 && sync
7141         expected=1
7142         cmd="$LFS find -size 5c -type f -lazy $dir"
7143         nums=$($cmd | wc -l)
7144         [ $nums -eq $expected ] ||
7145                 error "'$cmd' wrong: found $nums, expected $expected"
7146         cmd="$LFS find -size 5c -type f $dir"
7147         nums=$($cmd | wc -l)
7148         [ $nums -eq $expected ] ||
7149                 error "'$cmd' wrong: found $nums, expected $expected"
7150
7151         expected=1
7152         cmd="$LFS find -size +5c -type f -lazy $dir"
7153         nums=$($cmd | wc -l)
7154         [ $nums -eq $expected ] ||
7155                 error "'$cmd' wrong: found $nums, expected $expected"
7156         cmd="$LFS find -size +5c -type f $dir"
7157         nums=$($cmd | wc -l)
7158         [ $nums -eq $expected ] ||
7159                 error "'$cmd' wrong: found $nums, expected $expected"
7160
7161         expected=2
7162         cmd="$LFS find -size +0 -type f -lazy $dir"
7163         nums=$($cmd | wc -l)
7164         [ $nums -eq $expected ] ||
7165                 error "'$cmd' wrong: found $nums, expected $expected"
7166         cmd="$LFS find -size +0 -type f $dir"
7167         nums=$($cmd | wc -l)
7168         [ $nums -eq $expected ] ||
7169                 error "'$cmd' wrong: found $nums, expected $expected"
7170
7171         expected=2
7172         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] ||
7175                 error "'$cmd' wrong: found $nums, expected $expected"
7176         cmd="$LFS find ! -size -5c -type f $dir"
7177         nums=$($cmd | wc -l)
7178         [ $nums -eq $expected ] ||
7179                 error "'$cmd' wrong: found $nums, expected $expected"
7180
7181         expected=12
7182         cmd="$LFS find -size -5c -type f -lazy $dir"
7183         nums=$($cmd | wc -l)
7184         [ $nums -eq $expected ] ||
7185                 error "'$cmd' wrong: found $nums, expected $expected"
7186         cmd="$LFS find -size -5c -type f $dir"
7187         nums=$($cmd | wc -l)
7188         [ $nums -eq $expected ] ||
7189                 error "'$cmd' wrong: found $nums, expected $expected"
7190 }
7191 run_test 56r "check lfs find -size works"
7192
7193 test_56ra_sub() {
7194         local expected=$1
7195         local glimpses=$2
7196         local cmd="$3"
7197
7198         cancel_lru_locks $OSC
7199
7200         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7201         local nums=$($cmd | wc -l)
7202
7203         [ $nums -eq $expected ] ||
7204                 error "'$cmd' wrong: found $nums, expected $expected"
7205
7206         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7207
7208         if (( rpcs_before + glimpses != rpcs_after )); then
7209                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7210                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7211
7212                 if [[ $glimpses == 0 ]]; then
7213                         error "'$cmd' should not send glimpse RPCs to OST"
7214                 else
7215                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7216                 fi
7217         fi
7218 }
7219
7220 test_56ra() {
7221         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7222                 skip "MDS < 2.12.58 doesn't return LSOM data"
7223         local dir=$DIR/$tdir
7224         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7225
7226         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7227
7228         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7229         $LCTL set_param -n llite.*.statahead_agl=0
7230         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7231
7232         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7233         # open and close all files to ensure LSOM is updated
7234         cancel_lru_locks $OSC
7235         find $dir -type f | xargs cat > /dev/null
7236
7237         #   expect_found  glimpse_rpcs  command_to_run
7238         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7239         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7240         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7241         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7242
7243         echo "test" > $dir/$tfile
7244         echo "test2" > $dir/$tfile.2 && sync
7245         cancel_lru_locks $OSC
7246         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7247
7248         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7249         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7250         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7251         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7252
7253         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7254         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7255         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7256         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7257         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7258         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7259 }
7260 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7261
7262 test_56rb() {
7263         local dir=$DIR/$tdir
7264         local tmp=$TMP/$tfile.log
7265         local mdt_idx;
7266
7267         test_mkdir -p $dir || error "failed to mkdir $dir"
7268         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7269                 error "failed to setstripe $dir/$tfile"
7270         mdt_idx=$($LFS getdirstripe -i $dir)
7271         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7272
7273         stack_trap "rm -f $tmp" EXIT
7274         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7275         ! grep -q obd_uuid $tmp ||
7276                 error "failed to find --size +100K --ost 0 $dir"
7277         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7278         ! grep -q obd_uuid $tmp ||
7279                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7280 }
7281 run_test 56rb "check lfs find --size --ost/--mdt works"
7282
7283 test_56rc() {
7284         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7285         local dir=$DIR/$tdir
7286         local found
7287
7288         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7289         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7290         (( $MDSCOUNT > 2 )) &&
7291                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7292         mkdir $dir/$tdir-{1..10}
7293         touch $dir/$tfile-{1..10}
7294
7295         found=$($LFS find $dir --mdt-count 2 | wc -l)
7296         expect=11
7297         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7298
7299         found=$($LFS find $dir -T +1 | wc -l)
7300         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7301         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7302
7303         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7304         expect=11
7305         (( $found == $expect )) || error "found $found all_char, expect $expect"
7306
7307         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7308         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7309         (( $found == $expect )) || error "found $found all_char, expect $expect"
7310 }
7311 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7312
7313 test_56rd() {
7314         local dir=$DIR/$tdir
7315
7316         test_mkdir $dir
7317         rm -f $dir/*
7318
7319         mkfifo $dir/fifo || error "failed to create fifo file"
7320         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7321                 error "should not fail even cannot get projid from pipe file"
7322         found=$($LFS find $dir -t p --printf "%y")
7323         [[ "p" == $found ]] || error "found $found, expect p"
7324
7325         mknod $dir/chardev c 1 5 ||
7326                 error "failed to create character device file"
7327         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7328                 error "should not fail even cannot get projid from chardev file"
7329         found=$($LFS find $dir -t c --printf "%y")
7330         [[ "c" == $found ]] || error "found $found, expect c"
7331
7332         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7333         (( found == 2 )) || error "unable to list all files"
7334 }
7335 run_test 56rd "check lfs find --printf special files"
7336
7337 test_56s() { # LU-611 #LU-9369
7338         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7339
7340         local dir=$DIR/$tdir
7341         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7342
7343         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7344         for i in $(seq $NUMDIRS); do
7345                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7346         done
7347
7348         local expected=$NUMDIRS
7349         local cmd="$LFS find -c $OSTCOUNT $dir"
7350         local nums=$($cmd | wc -l)
7351
7352         [ $nums -eq $expected ] || {
7353                 $LFS getstripe -R $dir
7354                 error "'$cmd' wrong: found $nums, expected $expected"
7355         }
7356
7357         expected=$((NUMDIRS + onestripe))
7358         cmd="$LFS find -stripe-count +0 -type f $dir"
7359         nums=$($cmd | wc -l)
7360         [ $nums -eq $expected ] || {
7361                 $LFS getstripe -R $dir
7362                 error "'$cmd' wrong: found $nums, expected $expected"
7363         }
7364
7365         expected=$onestripe
7366         cmd="$LFS find -stripe-count 1 -type f $dir"
7367         nums=$($cmd | wc -l)
7368         [ $nums -eq $expected ] || {
7369                 $LFS getstripe -R $dir
7370                 error "'$cmd' wrong: found $nums, expected $expected"
7371         }
7372
7373         cmd="$LFS find -stripe-count -2 -type f $dir"
7374         nums=$($cmd | wc -l)
7375         [ $nums -eq $expected ] || {
7376                 $LFS getstripe -R $dir
7377                 error "'$cmd' wrong: found $nums, expected $expected"
7378         }
7379
7380         expected=0
7381         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7382         nums=$($cmd | wc -l)
7383         [ $nums -eq $expected ] || {
7384                 $LFS getstripe -R $dir
7385                 error "'$cmd' wrong: found $nums, expected $expected"
7386         }
7387 }
7388 run_test 56s "check lfs find -stripe-count works"
7389
7390 test_56t() { # LU-611 #LU-9369
7391         local dir=$DIR/$tdir
7392
7393         setup_56 $dir 0 $NUMDIRS
7394         for i in $(seq $NUMDIRS); do
7395                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7396         done
7397
7398         local expected=$NUMDIRS
7399         local cmd="$LFS find -S 8M $dir"
7400         local nums=$($cmd | wc -l)
7401
7402         [ $nums -eq $expected ] || {
7403                 $LFS getstripe -R $dir
7404                 error "'$cmd' wrong: found $nums, expected $expected"
7405         }
7406         rm -rf $dir
7407
7408         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7409
7410         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7411
7412         expected=$(((NUMDIRS + 1) * NUMFILES))
7413         cmd="$LFS find -stripe-size 512k -type f $dir"
7414         nums=$($cmd | wc -l)
7415         [ $nums -eq $expected ] ||
7416                 error "'$cmd' wrong: found $nums, expected $expected"
7417
7418         cmd="$LFS find -stripe-size +320k -type f $dir"
7419         nums=$($cmd | wc -l)
7420         [ $nums -eq $expected ] ||
7421                 error "'$cmd' wrong: found $nums, expected $expected"
7422
7423         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7424         cmd="$LFS find -stripe-size +200k -type f $dir"
7425         nums=$($cmd | wc -l)
7426         [ $nums -eq $expected ] ||
7427                 error "'$cmd' wrong: found $nums, expected $expected"
7428
7429         cmd="$LFS find -stripe-size -640k -type f $dir"
7430         nums=$($cmd | wc -l)
7431         [ $nums -eq $expected ] ||
7432                 error "'$cmd' wrong: found $nums, expected $expected"
7433
7434         expected=4
7435         cmd="$LFS find -stripe-size 256k -type f $dir"
7436         nums=$($cmd | wc -l)
7437         [ $nums -eq $expected ] ||
7438                 error "'$cmd' wrong: found $nums, expected $expected"
7439
7440         cmd="$LFS find -stripe-size -320k -type f $dir"
7441         nums=$($cmd | wc -l)
7442         [ $nums -eq $expected ] ||
7443                 error "'$cmd' wrong: found $nums, expected $expected"
7444
7445         expected=0
7446         cmd="$LFS find -stripe-size 1024k -type f $dir"
7447         nums=$($cmd | wc -l)
7448         [ $nums -eq $expected ] ||
7449                 error "'$cmd' wrong: found $nums, expected $expected"
7450 }
7451 run_test 56t "check lfs find -stripe-size works"
7452
7453 test_56u() { # LU-611
7454         local dir=$DIR/$tdir
7455
7456         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7457
7458         if [[ $OSTCOUNT -gt 1 ]]; then
7459                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7460                 onestripe=4
7461         else
7462                 onestripe=0
7463         fi
7464
7465         local expected=$(((NUMDIRS + 1) * NUMFILES))
7466         local cmd="$LFS find -stripe-index 0 -type f $dir"
7467         local nums=$($cmd | wc -l)
7468
7469         [ $nums -eq $expected ] ||
7470                 error "'$cmd' wrong: found $nums, expected $expected"
7471
7472         expected=$onestripe
7473         cmd="$LFS find -stripe-index 1 -type f $dir"
7474         nums=$($cmd | wc -l)
7475         [ $nums -eq $expected ] ||
7476                 error "'$cmd' wrong: found $nums, expected $expected"
7477
7478         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7479         nums=$($cmd | wc -l)
7480         [ $nums -eq $expected ] ||
7481                 error "'$cmd' wrong: found $nums, expected $expected"
7482
7483         expected=0
7484         # This should produce an error and not return any files
7485         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7486         nums=$($cmd 2>/dev/null | wc -l)
7487         [ $nums -eq $expected ] ||
7488                 error "'$cmd' wrong: found $nums, expected $expected"
7489
7490         if [[ $OSTCOUNT -gt 1 ]]; then
7491                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7492                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7493                 nums=$($cmd | wc -l)
7494                 [ $nums -eq $expected ] ||
7495                         error "'$cmd' wrong: found $nums, expected $expected"
7496         fi
7497 }
7498 run_test 56u "check lfs find -stripe-index works"
7499
7500 test_56v() {
7501         local mdt_idx=0
7502         local dir=$DIR/$tdir
7503
7504         setup_56 $dir $NUMFILES $NUMDIRS
7505
7506         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7507         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7508
7509         for file in $($LFS find -m $UUID $dir); do
7510                 file_midx=$($LFS getstripe -m $file)
7511                 [ $file_midx -eq $mdt_idx ] ||
7512                         error "lfs find -m $UUID != getstripe -m $file_midx"
7513         done
7514 }
7515 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7516
7517 test_56wa() {
7518         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7520
7521         local dir=$DIR/$tdir
7522
7523         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7524         stack_trap "rm -rf $dir"
7525
7526         local stripe_size=$($LFS getstripe -S -d $dir) ||
7527                 error "$LFS getstripe -S -d $dir failed"
7528         stripe_size=${stripe_size%% *}
7529
7530         local file_size=$((stripe_size * OSTCOUNT))
7531         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7532         local required_space=$((file_num * file_size))
7533         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7534                            head -n1)
7535         (( free_space >= required_space / 1024 )) ||
7536                 skip_env "need $required_space, have $free_space kbytes"
7537
7538         local dd_bs=65536
7539         local dd_count=$((file_size / dd_bs))
7540
7541         # write data into the files
7542         local i
7543         local j
7544         local file
7545
7546         for ((i = 1; i <= NUMFILES; i++ )); do
7547                 file=$dir/file$i
7548                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7549                         error "write data into $file failed"
7550         done
7551         for ((i = 1; i <= NUMDIRS; i++ )); do
7552                 for ((j = 1; j <= NUMFILES; j++ )); do
7553                         file=$dir/dir$i/file$j
7554                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7555                                 error "write data into $file failed"
7556                 done
7557         done
7558
7559         # $LFS_MIGRATE will fail if hard link migration is unsupported
7560         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7561                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7562                         error "creating links to $dir/dir1/file1 failed"
7563         fi
7564
7565         local expected=-1
7566
7567         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7568
7569         # lfs_migrate file
7570         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7571
7572         echo "$cmd"
7573         eval $cmd || error "$cmd failed"
7574
7575         check_stripe_count $dir/file1 $expected
7576
7577         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7578                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7579                 # OST 1 if it is on OST 0. This file is small enough to
7580                 # be on only one stripe.
7581                 file=$dir/migr_1_ost
7582                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7583                         error "write data into $file failed"
7584                 local obdidx=$($LFS getstripe -i $file)
7585                 local oldmd5=$(md5sum $file)
7586                 local newobdidx=0
7587
7588                 (( obdidx != 0 )) || newobdidx=1
7589                 cmd="$LFS migrate -i $newobdidx $file"
7590                 echo $cmd
7591                 eval $cmd || error "$cmd failed"
7592
7593                 local realobdix=$($LFS getstripe -i $file)
7594                 local newmd5=$(md5sum $file)
7595
7596                 (( $newobdidx == $realobdix )) ||
7597                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7598                 [[ "$oldmd5" == "$newmd5" ]] ||
7599                         error "md5sum differ: $oldmd5, $newmd5"
7600         fi
7601
7602         # lfs_migrate dir
7603         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7604         echo "$cmd"
7605         eval $cmd || error "$cmd failed"
7606
7607         for (( j = 1; j <= NUMFILES; j++ )); do
7608                 check_stripe_count $dir/dir1/file$j $expected
7609         done
7610
7611         # lfs_migrate works with lfs find
7612         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7613              $LFS_MIGRATE -y -c $expected"
7614         echo "$cmd"
7615         eval $cmd || error "$cmd failed"
7616
7617         for (( i = 2; i <= NUMFILES; i++ )); do
7618                 check_stripe_count $dir/file$i $expected
7619         done
7620         for (( i = 2; i <= NUMDIRS; i++ )); do
7621                 for (( j = 1; j <= NUMFILES; j++ )); do
7622                         check_stripe_count $dir/dir$i/file$j $expected
7623                 done
7624         done
7625 }
7626 run_test 56wa "check lfs_migrate -c stripe_count works"
7627
7628 test_56wb() {
7629         local file1=$DIR/$tdir/file1
7630         local create_pool=false
7631         local initial_pool=$($LFS getstripe -p $DIR)
7632         local pool_list=()
7633         local pool=""
7634
7635         echo -n "Creating test dir..."
7636         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7637         echo "done."
7638
7639         echo -n "Creating test file..."
7640         touch $file1 || error "cannot create file"
7641         echo "done."
7642
7643         echo -n "Detecting existing pools..."
7644         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7645
7646         if [ ${#pool_list[@]} -gt 0 ]; then
7647                 echo "${pool_list[@]}"
7648                 for thispool in "${pool_list[@]}"; do
7649                         if [[ -z "$initial_pool" ||
7650                               "$initial_pool" != "$thispool" ]]; then
7651                                 pool="$thispool"
7652                                 echo "Using existing pool '$pool'"
7653                                 break
7654                         fi
7655                 done
7656         else
7657                 echo "none detected."
7658         fi
7659         if [ -z "$pool" ]; then
7660                 pool=${POOL:-testpool}
7661                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7662                 echo -n "Creating pool '$pool'..."
7663                 create_pool=true
7664                 pool_add $pool &> /dev/null ||
7665                         error "pool_add failed"
7666                 echo "done."
7667
7668                 echo -n "Adding target to pool..."
7669                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7670                         error "pool_add_targets failed"
7671                 echo "done."
7672         fi
7673
7674         echo -n "Setting pool using -p option..."
7675         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7676                 error "migrate failed rc = $?"
7677         echo "done."
7678
7679         echo -n "Verifying test file is in pool after migrating..."
7680         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7681                 error "file was not migrated to pool $pool"
7682         echo "done."
7683
7684         echo -n "Removing test file from pool '$pool'..."
7685         # "lfs migrate $file" won't remove the file from the pool
7686         # until some striping information is changed.
7687         $LFS migrate -c 1 $file1 &> /dev/null ||
7688                 error "cannot remove from pool"
7689         [ "$($LFS getstripe -p $file1)" ] &&
7690                 error "pool still set"
7691         echo "done."
7692
7693         echo -n "Setting pool using --pool option..."
7694         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7695                 error "migrate failed rc = $?"
7696         echo "done."
7697
7698         # Clean up
7699         rm -f $file1
7700         if $create_pool; then
7701                 destroy_test_pools 2> /dev/null ||
7702                         error "destroy test pools failed"
7703         fi
7704 }
7705 run_test 56wb "check lfs_migrate pool support"
7706
7707 test_56wc() {
7708         local file1="$DIR/$tdir/$tfile"
7709         local md5
7710         local parent_ssize
7711         local parent_scount
7712         local cur_ssize
7713         local cur_scount
7714         local orig_ssize
7715         local new_scount
7716         local cur_comp
7717
7718         echo -n "Creating test dir..."
7719         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7720         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7721                 error "cannot set stripe by '-S 1M -c 1'"
7722         echo "done"
7723
7724         echo -n "Setting initial stripe for test file..."
7725         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7726                 error "cannot set stripe"
7727         cur_ssize=$($LFS getstripe -S "$file1")
7728         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7729         echo "done."
7730
7731         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7732         stack_trap "rm -f $file1"
7733         md5="$(md5sum $file1)"
7734
7735         # File currently set to -S 512K -c 1
7736
7737         # Ensure -c and -S options are rejected when -R is set
7738         echo -n "Verifying incompatible options are detected..."
7739         $LFS_MIGRATE -R -c 1 "$file1" &&
7740                 error "incompatible -R and -c options not detected"
7741         $LFS_MIGRATE -R -S 1M "$file1" &&
7742                 error "incompatible -R and -S options not detected"
7743         $LFS_MIGRATE -R -p pool "$file1" &&
7744                 error "incompatible -R and -p options not detected"
7745         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7746                 error "incompatible -R and -E options not detected"
7747         $LFS_MIGRATE -R -A "$file1" &&
7748                 error "incompatible -R and -A options not detected"
7749         $LFS_MIGRATE -A -c 1 "$file1" &&
7750                 error "incompatible -A and -c options not detected"
7751         $LFS_MIGRATE -A -S 1M "$file1" &&
7752                 error "incompatible -A and -S options not detected"
7753         $LFS_MIGRATE -A -p pool "$file1" &&
7754                 error "incompatible -A and -p options not detected"
7755         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7756                 error "incompatible -A and -E options not detected"
7757         echo "done."
7758
7759         # Ensure unrecognized options are passed through to 'lfs migrate'
7760         echo -n "Verifying -S option is passed through to lfs migrate..."
7761         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7762         cur_ssize=$($LFS getstripe -S "$file1")
7763         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7764         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7765         echo "done."
7766
7767         # File currently set to -S 1M -c 1
7768
7769         # Ensure long options are supported
7770         echo -n "Verifying long options supported..."
7771         $LFS_MIGRATE --non-block "$file1" ||
7772                 error "long option without argument not supported"
7773         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7774                 error "long option with argument not supported"
7775         cur_ssize=$($LFS getstripe -S "$file1")
7776         (( cur_ssize == 524288 )) ||
7777                 error "migrate --stripe-size $cur_ssize != 524288"
7778         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7779         echo "done."
7780
7781         # File currently set to -S 512K -c 1
7782
7783         if (( OSTCOUNT > 1 )); then
7784                 echo -n "Verifying explicit stripe count can be set..."
7785                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7786                 cur_scount=$($LFS getstripe -c "$file1")
7787                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7788                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7789                         error "file data has changed (3)"
7790                 echo "done."
7791         fi
7792
7793         # File currently set to -S 512K -c 1 or -S 512K -c 2
7794
7795         # Ensure parent striping is used if -R is set, and no stripe
7796         # count or size is specified
7797         echo -n "Setting stripe for parent directory..."
7798         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7799                 error "cannot set stripe '-S 2M -c 1'"
7800         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7801         echo "done."
7802
7803         echo -n "Verifying restripe option uses parent stripe settings..."
7804         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7805         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7806         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7807         cur_ssize=$($LFS getstripe -S "$file1")
7808         (( cur_ssize == parent_ssize )) ||
7809                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7810         cur_scount=$($LFS getstripe -c "$file1")
7811         (( cur_scount == parent_scount )) ||
7812                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7813         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7814         echo "done."
7815
7816         # File currently set to -S 1M -c 1
7817
7818         # Ensure striping is preserved if -R is not set, and no stripe
7819         # count or size is specified
7820         echo -n "Verifying striping size preserved when not specified..."
7821         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7822         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7823                 error "cannot set stripe on parent directory"
7824         $LFS_MIGRATE "$file1" || error "migrate failed"
7825         cur_ssize=$($LFS getstripe -S "$file1")
7826         (( cur_ssize == orig_ssize )) ||
7827                 error "migrate by default $cur_ssize != $orig_ssize"
7828         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7829         echo "done."
7830
7831         # Ensure file name properly detected when final option has no argument
7832         echo -n "Verifying file name properly detected..."
7833         $LFS_MIGRATE "$file1" ||
7834                 error "file name interpreted as option argument"
7835         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7836         echo "done."
7837
7838         # Ensure PFL arguments are passed through properly
7839         echo -n "Verifying PFL options passed through..."
7840         new_scount=$(((OSTCOUNT + 1) / 2))
7841         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7842                 error "migrate PFL arguments failed"
7843         cur_comp=$($LFS getstripe --comp-count $file1)
7844         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7845         cur_scount=$($LFS getstripe --stripe-count $file1)
7846         (( cur_scount == new_scount)) ||
7847                 error "PFL stripe count $cur_scount != $new_scount"
7848         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7849         echo "done."
7850 }
7851 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7852
7853 test_56wd() {
7854         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7855
7856         local file1=$DIR/$tdir/$tfile
7857
7858         echo -n "Creating test dir..."
7859         test_mkdir $DIR/$tdir || error "cannot create dir"
7860         echo "done."
7861
7862         echo -n "Creating test file..."
7863         echo "$tfile" > $file1
7864         echo "done."
7865
7866         # Ensure 'lfs migrate' will fail by using a non-existent option,
7867         # and make sure rsync is not called to recover
7868         echo -n "Make sure --no-rsync option works..."
7869         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7870                 grep -q 'refusing to fall back to rsync' ||
7871                 error "rsync was called with --no-rsync set"
7872         echo "done."
7873
7874         # Ensure rsync is called without trying 'lfs migrate' first
7875         echo -n "Make sure --rsync option works..."
7876         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7877                 grep -q 'falling back to rsync' &&
7878                 error "lfs migrate was called with --rsync set"
7879         echo "done."
7880 }
7881 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7882
7883 test_56we() {
7884         local td=$DIR/$tdir
7885         local tf=$td/$tfile
7886
7887         test_mkdir $td || error "cannot create $td"
7888         touch $tf || error "cannot touch $tf"
7889
7890         echo -n "Make sure --non-direct|-D works..."
7891         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7892                 grep -q "lfs migrate --non-direct" ||
7893                 error "--non-direct option cannot work correctly"
7894         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7895                 grep -q "lfs migrate -D" ||
7896                 error "-D option cannot work correctly"
7897         echo "done."
7898 }
7899 run_test 56we "check lfs_migrate --non-direct|-D support"
7900
7901 test_56x() {
7902         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7903         check_swap_layouts_support
7904
7905         local dir=$DIR/$tdir
7906         local ref1=/etc/passwd
7907         local file1=$dir/file1
7908
7909         test_mkdir $dir || error "creating dir $dir"
7910         $LFS setstripe -c 2 $file1
7911         cp $ref1 $file1
7912         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7913         stripe=$($LFS getstripe -c $file1)
7914         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7915         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7916
7917         # clean up
7918         rm -f $file1
7919 }
7920 run_test 56x "lfs migration support"
7921
7922 test_56xa() {
7923         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7924         check_swap_layouts_support
7925
7926         local dir=$DIR/$tdir/$testnum
7927
7928         test_mkdir -p $dir
7929
7930         local ref1=/etc/passwd
7931         local file1=$dir/file1
7932
7933         $LFS setstripe -c 2 $file1
7934         cp $ref1 $file1
7935         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7936
7937         local stripe=$($LFS getstripe -c $file1)
7938
7939         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7940         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7941
7942         # clean up
7943         rm -f $file1
7944 }
7945 run_test 56xa "lfs migration --block support"
7946
7947 check_migrate_links() {
7948         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7949         local dir="$1"
7950         local file1="$dir/file1"
7951         local begin="$2"
7952         local count="$3"
7953         local runas="$4"
7954         local total_count=$(($begin + $count - 1))
7955         local symlink_count=10
7956         local uniq_count=10
7957
7958         if [ ! -f "$file1" ]; then
7959                 echo -n "creating initial file..."
7960                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7961                         error "cannot setstripe initial file"
7962                 echo "done"
7963
7964                 echo -n "creating symlinks..."
7965                 for s in $(seq 1 $symlink_count); do
7966                         ln -s "$file1" "$dir/slink$s" ||
7967                                 error "cannot create symlinks"
7968                 done
7969                 echo "done"
7970
7971                 echo -n "creating nonlinked files..."
7972                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7973                         error "cannot create nonlinked files"
7974                 echo "done"
7975         fi
7976
7977         # create hard links
7978         if [ ! -f "$dir/file$total_count" ]; then
7979                 echo -n "creating hard links $begin:$total_count..."
7980                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7981                         /dev/null || error "cannot create hard links"
7982                 echo "done"
7983         fi
7984
7985         echo -n "checking number of hard links listed in xattrs..."
7986         local fid=$($LFS getstripe -F "$file1")
7987         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7988
7989         echo "${#paths[*]}"
7990         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7991                         skip "hard link list has unexpected size, skipping test"
7992         fi
7993         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7994                         error "link names should exceed xattrs size"
7995         fi
7996
7997         echo -n "migrating files..."
7998         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7999         local rc=$?
8000         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8001         echo "done"
8002
8003         # make sure all links have been properly migrated
8004         echo -n "verifying files..."
8005         fid=$($LFS getstripe -F "$file1") ||
8006                 error "cannot get fid for file $file1"
8007         for i in $(seq 2 $total_count); do
8008                 local fid2=$($LFS getstripe -F $dir/file$i)
8009
8010                 [ "$fid2" == "$fid" ] ||
8011                         error "migrated hard link has mismatched FID"
8012         done
8013
8014         # make sure hard links were properly detected, and migration was
8015         # performed only once for the entire link set; nonlinked files should
8016         # also be migrated
8017         local actual=$(grep -c 'done' <<< "$migrate_out")
8018         local expected=$(($uniq_count + 1))
8019
8020         [ "$actual" -eq  "$expected" ] ||
8021                 error "hard links individually migrated ($actual != $expected)"
8022
8023         # make sure the correct number of hard links are present
8024         local hardlinks=$(stat -c '%h' "$file1")
8025
8026         [ $hardlinks -eq $total_count ] ||
8027                 error "num hard links $hardlinks != $total_count"
8028         echo "done"
8029
8030         return 0
8031 }
8032
8033 test_56xb() {
8034         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8035                 skip "Need MDS version at least 2.10.55"
8036
8037         local dir="$DIR/$tdir"
8038
8039         test_mkdir "$dir" || error "cannot create dir $dir"
8040
8041         echo "testing lfs migrate mode when all links fit within xattrs"
8042         check_migrate_links "$dir" 2 99
8043
8044         echo "testing rsync mode when all links fit within xattrs"
8045         check_migrate_links --rsync "$dir" 2 99
8046
8047         echo "testing lfs migrate mode when all links do not fit within xattrs"
8048         check_migrate_links "$dir" 101 100
8049
8050         echo "testing rsync mode when all links do not fit within xattrs"
8051         check_migrate_links --rsync "$dir" 101 100
8052
8053         chown -R $RUNAS_ID $dir
8054         echo "testing non-root lfs migrate mode when not all links are in xattr"
8055         check_migrate_links "$dir" 101 100 "$RUNAS"
8056
8057         # clean up
8058         rm -rf $dir
8059 }
8060 run_test 56xb "lfs migration hard link support"
8061
8062 test_56xc() {
8063         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8064
8065         local dir="$DIR/$tdir"
8066
8067         test_mkdir "$dir" || error "cannot create dir $dir"
8068
8069         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8070         echo -n "Setting initial stripe for 20MB test file..."
8071         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8072                 error "cannot setstripe 20MB file"
8073         echo "done"
8074         echo -n "Sizing 20MB test file..."
8075         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8076         echo "done"
8077         echo -n "Verifying small file autostripe count is 1..."
8078         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8079                 error "cannot migrate 20MB file"
8080         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8081                 error "cannot get stripe for $dir/20mb"
8082         [ $stripe_count -eq 1 ] ||
8083                 error "unexpected stripe count $stripe_count for 20MB file"
8084         rm -f "$dir/20mb"
8085         echo "done"
8086
8087         # Test 2: File is small enough to fit within the available space on
8088         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8089         # have at least an additional 1KB for each desired stripe for test 3
8090         echo -n "Setting stripe for 1GB test file..."
8091         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8092         echo "done"
8093         echo -n "Sizing 1GB test file..."
8094         # File size is 1GB + 3KB
8095         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8096         echo "done"
8097
8098         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8099         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8100         if (( avail > 524288 * OSTCOUNT )); then
8101                 echo -n "Migrating 1GB file..."
8102                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8103                         error "cannot migrate 1GB file"
8104                 echo "done"
8105                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8106                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8107                         error "cannot getstripe for 1GB file"
8108                 [ $stripe_count -eq 2 ] ||
8109                         error "unexpected stripe count $stripe_count != 2"
8110                 echo "done"
8111         fi
8112
8113         # Test 3: File is too large to fit within the available space on
8114         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8115         if [ $OSTCOUNT -ge 3 ]; then
8116                 # The required available space is calculated as
8117                 # file size (1GB + 3KB) / OST count (3).
8118                 local kb_per_ost=349526
8119
8120                 echo -n "Migrating 1GB file with limit..."
8121                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8122                         error "cannot migrate 1GB file with limit"
8123                 echo "done"
8124
8125                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8126                 echo -n "Verifying 1GB autostripe count with limited space..."
8127                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8128                         error "unexpected stripe count $stripe_count (min 3)"
8129                 echo "done"
8130         fi
8131
8132         # clean up
8133         rm -rf $dir
8134 }
8135 run_test 56xc "lfs migration autostripe"
8136
8137 test_56xd() {
8138         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8139
8140         local dir=$DIR/$tdir
8141         local f_mgrt=$dir/$tfile.mgrt
8142         local f_yaml=$dir/$tfile.yaml
8143         local f_copy=$dir/$tfile.copy
8144         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8145         local layout_copy="-c 2 -S 2M -i 1"
8146         local yamlfile=$dir/yamlfile
8147         local layout_before;
8148         local layout_after;
8149
8150         test_mkdir "$dir" || error "cannot create dir $dir"
8151         stack_trap "rm -rf $dir"
8152         $LFS setstripe $layout_yaml $f_yaml ||
8153                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8154         $LFS getstripe --yaml $f_yaml > $yamlfile
8155         $LFS setstripe $layout_copy $f_copy ||
8156                 error "cannot setstripe $f_copy with layout $layout_copy"
8157         touch $f_mgrt
8158         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8159
8160         # 1. test option --yaml
8161         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8162                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8163         layout_before=$(get_layout_param $f_yaml)
8164         layout_after=$(get_layout_param $f_mgrt)
8165         [ "$layout_after" == "$layout_before" ] ||
8166                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8167
8168         # 2. test option --copy
8169         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8170                 error "cannot migrate $f_mgrt with --copy $f_copy"
8171         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8172         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8173         [ "$layout_after" == "$layout_before" ] ||
8174                 error "lfs_migrate --copy: $layout_after != $layout_before"
8175 }
8176 run_test 56xd "check lfs_migrate --yaml and --copy support"
8177
8178 test_56xe() {
8179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8180
8181         local dir=$DIR/$tdir
8182         local f_comp=$dir/$tfile
8183         local layout="-E 1M -S 512K -E 2M -c 2 -E 3M -c 2 -E eof -c $OSTCOUNT"
8184         local layout_before=""
8185         local layout_after=""
8186
8187         test_mkdir "$dir" || error "cannot create dir $dir"
8188         stack_trap "rm -rf $dir"
8189         $LFS setstripe $layout $f_comp ||
8190                 error "cannot setstripe $f_comp with layout $layout"
8191         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8192         dd if=/dev/zero of=$f_comp bs=1M count=4
8193
8194         # 1. migrate a comp layout file by lfs_migrate
8195         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8196         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8197         idx_before=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8198                      tr '\n' ' ')
8199         [ "$layout_before" == "$layout_after" ] ||
8200                 error "lfs_migrate: $layout_before != $layout_after"
8201
8202         # 2. migrate a comp layout file by lfs migrate
8203         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8204         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8205         idx_after=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8206                      tr '\n' ' ')
8207         [ "$layout_before" == "$layout_after" ] ||
8208                 error "lfs migrate: $layout_before != $layout_after"
8209
8210         # this may not fail every time with a broken lfs migrate, but will fail
8211         # often enough to notice, and will not have false positives very often
8212         [ "$idx_before" != "$idx_after" ] ||
8213                 error "lfs migrate: $idx_before == $idx_after"
8214 }
8215 run_test 56xe "migrate a composite layout file"
8216
8217 test_56xf() {
8218         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8219
8220         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8221                 skip "Need server version at least 2.13.53"
8222
8223         local dir=$DIR/$tdir
8224         local f_comp=$dir/$tfile
8225         local layout="-E 1M -c1 -E -1 -c2"
8226         local fid_before=""
8227         local fid_after=""
8228
8229         test_mkdir "$dir" || error "cannot create dir $dir"
8230         stack_trap "rm -rf $dir"
8231         $LFS setstripe $layout $f_comp ||
8232                 error "cannot setstripe $f_comp with layout $layout"
8233         fid_before=$($LFS getstripe --fid $f_comp)
8234         dd if=/dev/zero of=$f_comp bs=1M count=4
8235
8236         # 1. migrate a comp layout file to a comp layout
8237         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8238         fid_after=$($LFS getstripe --fid $f_comp)
8239         [ "$fid_before" == "$fid_after" ] ||
8240                 error "comp-to-comp migrate: $fid_before != $fid_after"
8241
8242         # 2. migrate a comp layout file to a plain layout
8243         $LFS migrate -c2 $f_comp ||
8244                 error "cannot migrate $f_comp by lfs migrate"
8245         fid_after=$($LFS getstripe --fid $f_comp)
8246         [ "$fid_before" == "$fid_after" ] ||
8247                 error "comp-to-plain migrate: $fid_before != $fid_after"
8248
8249         # 3. migrate a plain layout file to a comp layout
8250         $LFS migrate $layout $f_comp ||
8251                 error "cannot migrate $f_comp by lfs migrate"
8252         fid_after=$($LFS getstripe --fid $f_comp)
8253         [ "$fid_before" == "$fid_after" ] ||
8254                 error "plain-to-comp migrate: $fid_before != $fid_after"
8255 }
8256 run_test 56xf "FID is not lost during migration of a composite layout file"
8257
8258 check_file_ost_range() {
8259         local file="$1"
8260         shift
8261         local range="$*"
8262         local -a file_range
8263         local idx
8264
8265         file_range=($($LFS getstripe -y "$file" |
8266                 awk '/l_ost_idx:/ { print $NF }'))
8267
8268         if [[ "${#file_range[@]}" = 0 ]]; then
8269                 echo "No osts found for $file"
8270                 return 1
8271         fi
8272
8273         for idx in "${file_range[@]}"; do
8274                 [[ " $range " =~ " $idx " ]] ||
8275                         return 1
8276         done
8277
8278         return 0
8279 }
8280
8281 sub_test_56xg() {
8282         local stripe_opt="$1"
8283         local pool="$2"
8284         shift 2
8285         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8286
8287         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8288                 error "Fail to migrate $tfile on $pool"
8289         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8290                 error "$tfile is not in pool $pool"
8291         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8292                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8293 }
8294
8295 test_56xg() {
8296         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8297         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8298         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8299                 skip "Need MDS version newer than 2.14.52"
8300
8301         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8302         local -a pool_ranges=("0 0" "1 1" "0 1")
8303
8304         # init pools
8305         for i in "${!pool_names[@]}"; do
8306                 pool_add ${pool_names[$i]} ||
8307                         error "pool_add failed (pool: ${pool_names[$i]})"
8308                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8309                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8310         done
8311
8312         # init the file to migrate
8313         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8314                 error "Unable to create $tfile on OST1"
8315         stack_trap "rm -f $DIR/$tfile"
8316         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8317                 error "Unable to write on $tfile"
8318
8319         echo "1. migrate $tfile on pool ${pool_names[0]}"
8320         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8321
8322         echo "2. migrate $tfile on pool ${pool_names[2]}"
8323         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8324
8325         echo "3. migrate $tfile on pool ${pool_names[1]}"
8326         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8327
8328         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8329         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8330         echo
8331
8332         # Clean pools
8333         destroy_test_pools ||
8334                 error "pool_destroy failed"
8335 }
8336 run_test 56xg "lfs migrate pool support"
8337
8338 test_56xh() {
8339         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8340
8341         local size_mb=25
8342         local file1=$DIR/$tfile
8343         local tmp1=$TMP/$tfile.tmp
8344
8345         $LFS setstripe -c 2 $file1
8346
8347         stack_trap "rm -f $file1 $tmp1"
8348         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8349                         error "error creating $tmp1"
8350         ls -lsh $tmp1
8351         cp $tmp1 $file1
8352
8353         local start=$SECONDS
8354
8355         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8356                 error "migrate failed rc = $?"
8357
8358         local elapsed=$((SECONDS - start))
8359
8360         # with 1MB/s, elapsed should equal size_mb
8361         (( elapsed >= size_mb * 95 / 100 )) ||
8362                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8363
8364         (( elapsed <= size_mb * 120 / 100 )) ||
8365                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8366
8367         (( elapsed <= size_mb * 350 / 100 )) ||
8368                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8369
8370         stripe=$($LFS getstripe -c $file1)
8371         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8372         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8373
8374         # Clean up file (since it is multiple MB)
8375         rm -f $file1 $tmp1
8376 }
8377 run_test 56xh "lfs migrate bandwidth limitation support"
8378
8379 test_56xi() {
8380         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8381         verify_yaml_available || skip_env "YAML verification not installed"
8382
8383         local size_mb=5
8384         local file1=$DIR/$tfile.1
8385         local file2=$DIR/$tfile.2
8386         local file3=$DIR/$tfile.3
8387         local output_file=$DIR/$tfile.out
8388         local tmp1=$TMP/$tfile.tmp
8389
8390         $LFS setstripe -c 2 $file1
8391         $LFS setstripe -c 2 $file2
8392         $LFS setstripe -c 2 $file3
8393
8394         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8395         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8396                         error "error creating $tmp1"
8397         ls -lsh $tmp1
8398         cp $tmp1 $file1
8399         cp $tmp1 $file2
8400         cp $tmp1 $file3
8401
8402         $LFS migrate --stats --stats-interval=1 \
8403                 -c 1 $file1 $file2 $file3 1> $output_file ||
8404                 error "migrate failed rc = $?"
8405
8406         cat $output_file
8407         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8408
8409         # Clean up file (since it is multiple MB)
8410         rm -f $file1 $file2 $file3 $tmp1 $output_file
8411 }
8412 run_test 56xi "lfs migrate stats support"
8413
8414 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8415         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8416
8417         local file=$DIR/$tfile
8418         local linkdir=$DIR/$tdir
8419
8420         test_mkdir $linkdir || error "fail to create $linkdir"
8421         $LFS setstripe -i 0 -c 1 -S1M $file
8422         stack_trap "rm -rf $file $linkdir"
8423         dd if=/dev/urandom of=$file bs=1M count=10 ||
8424                 error "fail to create $file"
8425
8426         # Create file links
8427         local cpts
8428         local threads_max
8429         local nlinks
8430
8431         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8432         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8433         (( nlinks = thread_max * 3 / 2 / cpts))
8434
8435         echo "create $nlinks hard links of $file"
8436         createmany -l $file $linkdir/link $nlinks
8437
8438         # Parallel migrates (should not block)
8439         local i
8440         for ((i = 0; i < nlinks; i++)); do
8441                 echo $linkdir/link$i
8442         done | xargs -n1 -P $nlinks $LFS migrate -c2
8443
8444         local stripe_count
8445         stripe_count=$($LFS getstripe -c $file) ||
8446                 error "fail to get stripe count on $file"
8447
8448         ((stripe_count == 2)) ||
8449                 error "fail to migrate $file (stripe_count = $stripe_count)"
8450 }
8451 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8452
8453 test_56xk() {
8454         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8455
8456         local size_mb=5
8457         local file1=$DIR/$tfile
8458
8459         stack_trap "rm -f $file1"
8460         $LFS setstripe -c 1 $file1
8461         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8462                 error "error creating $file1"
8463         $LFS mirror extend -N $file1 || error "can't mirror"
8464         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8465                 error "can't dd"
8466         $LFS getstripe $file1 | grep stale ||
8467                 error "one component must be stale"
8468
8469         local start=$SECONDS
8470         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8471                 error "migrate failed rc = $?"
8472         local elapsed=$((SECONDS - start))
8473         $LFS getstripe $file1 | grep stale &&
8474                 error "all components must be sync"
8475
8476         # with 1MB/s, elapsed should equal size_mb
8477         (( elapsed >= size_mb * 95 / 100 )) ||
8478                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8479
8480         (( elapsed <= size_mb * 120 / 100 )) ||
8481                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8482
8483         (( elapsed <= size_mb * 350 / 100 )) ||
8484                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8485 }
8486 run_test 56xk "lfs mirror resync bandwidth limitation support"
8487
8488 test_56xl() {
8489         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8490         verify_yaml_available || skip_env "YAML verification not installed"
8491
8492         local size_mb=5
8493         local file1=$DIR/$tfile.1
8494         local output_file=$DIR/$tfile.out
8495
8496         stack_trap "rm -f $file1"
8497         $LFS setstripe -c 1 $file1
8498         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8499                 error "error creating $file1"
8500         $LFS mirror extend -N $file1 || error "can't mirror"
8501         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8502                 error "can't dd"
8503         $LFS getstripe $file1 | grep stale ||
8504                 error "one component must be stale"
8505         $LFS getstripe $file1
8506
8507         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8508                 error "resync failed rc = $?"
8509         $LFS getstripe $file1 | grep stale &&
8510                 error "all components must be sync"
8511
8512         cat $output_file
8513         cat $output_file | verify_yaml || error "stats is not valid YAML"
8514 }
8515 run_test 56xl "lfs mirror resync stats support"
8516
8517 test_56y() {
8518         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8519                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8520
8521         local res=""
8522         local dir=$DIR/$tdir
8523         local f1=$dir/file1
8524         local f2=$dir/file2
8525
8526         test_mkdir -p $dir || error "creating dir $dir"
8527         touch $f1 || error "creating std file $f1"
8528         $MULTIOP $f2 H2c || error "creating released file $f2"
8529
8530         # a directory can be raid0, so ask only for files
8531         res=$($LFS find $dir -L raid0 -type f | wc -l)
8532         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8533
8534         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8535         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8536
8537         # only files can be released, so no need to force file search
8538         res=$($LFS find $dir -L released)
8539         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8540
8541         res=$($LFS find $dir -type f \! -L released)
8542         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8543 }
8544 run_test 56y "lfs find -L raid0|released"
8545
8546 test_56z() { # LU-4824
8547         # This checks to make sure 'lfs find' continues after errors
8548         # There are two classes of errors that should be caught:
8549         # - If multiple paths are provided, all should be searched even if one
8550         #   errors out
8551         # - If errors are encountered during the search, it should not terminate
8552         #   early
8553         local dir=$DIR/$tdir
8554         local i
8555
8556         test_mkdir $dir
8557         for i in d{0..9}; do
8558                 test_mkdir $dir/$i
8559                 touch $dir/$i/$tfile
8560         done
8561         $LFS find $DIR/non_existent_dir $dir &&
8562                 error "$LFS find did not return an error"
8563         # Make a directory unsearchable. This should NOT be the last entry in
8564         # directory order.  Arbitrarily pick the 6th entry
8565         chmod 700 $($LFS find $dir -type d | sed '6!d')
8566
8567         $RUNAS $LFS find $DIR/non_existent $dir
8568         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8569
8570         # The user should be able to see 10 directories and 9 files
8571         (( count == 19 )) ||
8572                 error "$LFS find found $count != 19 entries after error"
8573 }
8574 run_test 56z "lfs find should continue after an error"
8575
8576 test_56aa() { # LU-5937
8577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8578
8579         local dir=$DIR/$tdir
8580
8581         mkdir $dir
8582         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8583
8584         createmany -o $dir/striped_dir/${tfile}- 1024
8585         local dirs=$($LFS find --size +8k $dir/)
8586
8587         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8588 }
8589 run_test 56aa "lfs find --size under striped dir"
8590
8591 test_56ab() { # LU-10705
8592         test_mkdir $DIR/$tdir
8593         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8594         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8595         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8596         # Flush writes to ensure valid blocks.  Need to be more thorough for
8597         # ZFS, since blocks are not allocated/returned to client immediately.
8598         sync_all_data
8599         wait_zfs_commit ost1 2
8600         cancel_lru_locks osc
8601         ls -ls $DIR/$tdir
8602
8603         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8604
8605         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8606
8607         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8608         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8609
8610         rm -f $DIR/$tdir/$tfile.[123]
8611 }
8612 run_test 56ab "lfs find --blocks"
8613
8614 # LU-11188
8615 test_56aca() {
8616         local dir="$DIR/$tdir"
8617         local perms=(001 002 003 004 005 006 007
8618                      010 020 030 040 050 060 070
8619                      100 200 300 400 500 600 700
8620                      111 222 333 444 555 666 777)
8621         local perm_minus=(8 8 4 8 4 4 2
8622                           8 8 4 8 4 4 2
8623                           8 8 4 8 4 4 2
8624                           4 4 2 4 2 2 1)
8625         local perm_slash=(8  8 12  8 12 12 14
8626                           8  8 12  8 12 12 14
8627                           8  8 12  8 12 12 14
8628                          16 16 24 16 24 24 28)
8629
8630         test_mkdir "$dir"
8631         for perm in ${perms[*]}; do
8632                 touch "$dir/$tfile.$perm"
8633                 chmod $perm "$dir/$tfile.$perm"
8634         done
8635
8636         for ((i = 0; i < ${#perms[*]}; i++)); do
8637                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8638                 (( $num == 1 )) ||
8639                         error "lfs find -perm ${perms[i]}:"\
8640                               "$num != 1"
8641
8642                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8643                 (( $num == ${perm_minus[i]} )) ||
8644                         error "lfs find -perm -${perms[i]}:"\
8645                               "$num != ${perm_minus[i]}"
8646
8647                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8648                 (( $num == ${perm_slash[i]} )) ||
8649                         error "lfs find -perm /${perms[i]}:"\
8650                               "$num != ${perm_slash[i]}"
8651         done
8652 }
8653 run_test 56aca "check lfs find -perm with octal representation"
8654
8655 test_56acb() {
8656         local dir=$DIR/$tdir
8657         # p is the permission of write and execute for user, group and other
8658         # without the umask. It is used to test +wx.
8659         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8660         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8661         local symbolic=(+t  a+t u+t g+t o+t
8662                         g+s u+s o+s +s o+sr
8663                         o=r,ug+o,u+w
8664                         u+ g+ o+ a+ ugo+
8665                         u- g- o- a- ugo-
8666                         u= g= o= a= ugo=
8667                         o=r,ug+o,u+w u=r,a+u,u+w
8668                         g=r,ugo=g,u+w u+x,+X +X
8669                         u+x,u+X u+X u+x,g+X o+r,+X
8670                         u+x,go+X +wx +rwx)
8671
8672         test_mkdir $dir
8673         for perm in ${perms[*]}; do
8674                 touch "$dir/$tfile.$perm"
8675                 chmod $perm "$dir/$tfile.$perm"
8676         done
8677
8678         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8679                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8680
8681                 (( $num == 1 )) ||
8682                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8683         done
8684 }
8685 run_test 56acb "check lfs find -perm with symbolic representation"
8686
8687 test_56acc() {
8688         local dir=$DIR/$tdir
8689         local tests="17777 787 789 abcd
8690                 ug=uu ug=a ug=gu uo=ou urw
8691                 u+xg+x a=r,u+x,"
8692
8693         test_mkdir $dir
8694         for err in $tests; do
8695                 if $LFS find $dir -perm $err 2>/dev/null; then
8696                         error "lfs find -perm $err: parsing should have failed"
8697                 fi
8698         done
8699 }
8700 run_test 56acc "check parsing error for lfs find -perm"
8701
8702 test_56ba() {
8703         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8704                 skip "Need MDS version at least 2.10.50"
8705
8706         # Create composite files with one component
8707         local dir=$DIR/$tdir
8708
8709         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8710         # Create composite files with three components
8711         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8712         # LU-16904 Create plain layout files
8713         lfs setstripe -c 1 $dir/$tfile-{1..10}
8714
8715         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8716
8717         [[ $nfiles == 10 ]] ||
8718                 error "lfs find -E 1M found $nfiles != 10 files"
8719
8720         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8721         [[ $nfiles == 25 ]] ||
8722                 error "lfs find ! -E 1M found $nfiles != 25 files"
8723
8724         # All files have a component that starts at 0
8725         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8726         [[ $nfiles == 35 ]] ||
8727                 error "lfs find --component-start 0 - $nfiles != 35 files"
8728
8729         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8730         [[ $nfiles == 15 ]] ||
8731                 error "lfs find --component-start 2M - $nfiles != 15 files"
8732
8733         # All files created here have a componenet that does not starts at 2M
8734         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8735         [[ $nfiles == 35 ]] ||
8736                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8737
8738         # Find files with a specified number of components
8739         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8740         [[ $nfiles == 15 ]] ||
8741                 error "lfs find --component-count 3 - $nfiles != 15 files"
8742
8743         # Remember non-composite files have a component count of zero
8744         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8745         [[ $nfiles == 10 ]] ||
8746                 error "lfs find --component-count 0 - $nfiles != 10 files"
8747
8748         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8749         [[ $nfiles == 20 ]] ||
8750                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8751
8752         # All files have a flag called "init"
8753         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8754         [[ $nfiles == 35 ]] ||
8755                 error "lfs find --component-flags init - $nfiles != 35 files"
8756
8757         # Multi-component files will have a component not initialized
8758         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8759         [[ $nfiles == 15 ]] ||
8760                 error "lfs find !--component-flags init - $nfiles != 15 files"
8761
8762         rm -rf $dir
8763
8764 }
8765 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8766
8767 test_56ca() {
8768         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8769                 skip "Need MDS version at least 2.10.57"
8770
8771         local td=$DIR/$tdir
8772         local tf=$td/$tfile
8773         local dir
8774         local nfiles
8775         local cmd
8776         local i
8777         local j
8778
8779         # create mirrored directories and mirrored files
8780         mkdir $td || error "mkdir $td failed"
8781         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8782         createmany -o $tf- 10 || error "create $tf- failed"
8783
8784         for i in $(seq 2); do
8785                 dir=$td/dir$i
8786                 mkdir $dir || error "mkdir $dir failed"
8787                 $LFS mirror create -N$((3 + i)) $dir ||
8788                         error "create mirrored dir $dir failed"
8789                 createmany -o $dir/$tfile- 10 ||
8790                         error "create $dir/$tfile- failed"
8791         done
8792
8793         # change the states of some mirrored files
8794         echo foo > $tf-6
8795         for i in $(seq 2); do
8796                 dir=$td/dir$i
8797                 for j in $(seq 4 9); do
8798                         echo foo > $dir/$tfile-$j
8799                 done
8800         done
8801
8802         # find mirrored files with specific mirror count
8803         cmd="$LFS find --mirror-count 3 --type f $td"
8804         nfiles=$($cmd | wc -l)
8805         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8806
8807         cmd="$LFS find ! --mirror-count 3 --type f $td"
8808         nfiles=$($cmd | wc -l)
8809         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8810
8811         cmd="$LFS find --mirror-count +2 --type f $td"
8812         nfiles=$($cmd | wc -l)
8813         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8814
8815         cmd="$LFS find --mirror-count -6 --type f $td"
8816         nfiles=$($cmd | wc -l)
8817         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8818
8819         # find mirrored files with specific file state
8820         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8821         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8822
8823         cmd="$LFS find --mirror-state=ro --type f $td"
8824         nfiles=$($cmd | wc -l)
8825         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8826
8827         cmd="$LFS find ! --mirror-state=ro --type f $td"
8828         nfiles=$($cmd | wc -l)
8829         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8830
8831         cmd="$LFS find --mirror-state=wp --type f $td"
8832         nfiles=$($cmd | wc -l)
8833         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8834
8835         cmd="$LFS find ! --mirror-state=sp --type f $td"
8836         nfiles=$($cmd | wc -l)
8837         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8838 }
8839 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8840
8841 test_56da() { # LU-14179
8842         local path=$DIR/$tdir
8843
8844         test_mkdir $path
8845         cd $path
8846
8847         local longdir=$(str_repeat 'a' 255)
8848
8849         for i in {1..15}; do
8850                 path=$path/$longdir
8851                 test_mkdir $longdir
8852                 cd $longdir
8853         done
8854
8855         local len=${#path}
8856         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8857
8858         test_mkdir $lastdir
8859         cd $lastdir
8860         # PATH_MAX-1
8861         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8862
8863         # NAME_MAX
8864         touch $(str_repeat 'f' 255)
8865
8866         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8867                 error "lfs find reported an error"
8868
8869         rm -rf $DIR/$tdir
8870 }
8871 run_test 56da "test lfs find with long paths"
8872
8873 test_56ea() { #LU-10378
8874         local path=$DIR/$tdir
8875         local pool=$TESTNAME
8876
8877         # Create ost pool
8878         pool_add $pool || error "pool_add $pool failed"
8879         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8880                 error "adding targets to $pool failed"
8881
8882         # Set default pool on directory before creating file
8883         mkdir $path || error "mkdir $path failed"
8884         $LFS setstripe -p $pool $path ||
8885                 error "set OST pool on $pool failed"
8886         touch $path/$tfile || error "touch $path/$tfile failed"
8887
8888         # Compare basic file attributes from -printf and stat
8889         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8890         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8891
8892         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8893                 error "Attrs from lfs find and stat don't match"
8894
8895         # Compare Lustre attributes from lfs find and lfs getstripe
8896         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8897         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8898         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8899         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8900         local fpool=$($LFS getstripe --pool $path/$tfile)
8901         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8902
8903         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8904                 error "Attrs from lfs find and lfs getstripe don't match"
8905
8906         # Verify behavior for unknown escape/format sequences
8907         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8908
8909         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8910                 error "Escape/format codes don't match"
8911 }
8912 run_test 56ea "test lfs find -printf option"
8913
8914 test_56eb() {
8915         local dir=$DIR/$tdir
8916         local subdir_1=$dir/subdir_1
8917
8918         test_mkdir -p $subdir_1
8919         ln -s subdir_1 $dir/link_1
8920
8921         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8922                 error "symlink is not followed"
8923
8924         $LFS getstripe --no-follow $dir |
8925                 grep "^$dir/link_1 has no stripe info$" ||
8926                 error "symlink should not have stripe info"
8927
8928         touch $dir/testfile
8929         ln -s testfile $dir/file_link_2
8930
8931         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8932                 error "symlink is not followed"
8933
8934         $LFS getstripe --no-follow $dir |
8935                 grep "^$dir/file_link_2 has no stripe info$" ||
8936                 error "symlink should not have stripe info"
8937 }
8938 run_test 56eb "check lfs getstripe on symlink"
8939
8940 test_56ec() {
8941         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8942         local dir=$DIR/$tdir
8943         local srcfile=$dir/srcfile
8944         local srcyaml=$dir/srcyaml
8945         local destfile=$dir/destfile
8946
8947         test_mkdir -p $dir
8948
8949         $LFS setstripe -i 1 $srcfile
8950         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8951         # if the setstripe yaml parsing fails for any reason, the command can
8952         # randomly assign the correct OST index, leading to an erroneous
8953         # success. but the chance of false success is low enough that a
8954         # regression should still be quickly caught.
8955         $LFS setstripe --yaml=$srcyaml $destfile
8956
8957         local srcindex=$($LFS getstripe -i $srcfile)
8958         local destindex=$($LFS getstripe -i $destfile)
8959
8960         if [[ ! $srcindex -eq $destindex ]]; then
8961                 error "setstripe did not set OST index correctly"
8962         fi
8963 }
8964 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8965
8966 test_56eda() {
8967         local dir=$DIR/$tdir
8968         local subdir=$dir/subdir
8969         local file1=$dir/$tfile
8970         local file2=$dir/$tfile\2
8971         local link=$dir/$tfile-link
8972         local nfiles
8973
8974         test_mkdir -p $dir
8975         $LFS setdirstripe -c1 $subdir
8976         touch $file1
8977         touch $file2
8978         ln $file2 $link
8979
8980         nfiles=$($LFS find --links 1 $dir | wc -l)
8981         (( $nfiles == 1 )) ||
8982                 error "lfs find --links expected 1 file, got $nfiles"
8983
8984         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8985         (( $nfiles == 2 )) ||
8986                 error "lfs find --links expected 2 files, got $nfiles"
8987
8988         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8989         (( $nfiles == 1 )) ||
8990                 error "lfs find --links expected 1 directory, got $nfiles"
8991 }
8992 run_test 56eda "check lfs find --links"
8993
8994 test_56edb() {
8995         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8996
8997         local dir=$DIR/$tdir
8998         local stripedir=$dir/stripedir
8999         local nfiles
9000
9001         test_mkdir -p $dir
9002
9003         $LFS setdirstripe -c2 $stripedir
9004
9005         $LFS getdirstripe $stripedir
9006
9007         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9008         (( $nfiles == 1 )) ||
9009                 error "lfs find --links expected 1 directory, got $nfiles"
9010 }
9011 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9012
9013 test_56ef() {
9014         local dir=$DIR/$tdir
9015         local dir1=$dir/d1
9016         local dir2=$dir/d2
9017         local nfiles
9018         local err_msg
9019
9020         test_mkdir -p $dir
9021
9022         mkdir $dir1
9023         mkdir $dir2
9024
9025         touch $dir1/f
9026         touch $dir2/f
9027
9028         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9029         (( $nfiles == 2 )) ||
9030                 error "(1) lfs find expected 2 files, got $nfiles"
9031
9032         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9033         (( $nfiles == 2 )) ||
9034                 error "(2) lfs find expected 2 files, got $nfiles"
9035
9036         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9037         (( $nfiles == 2 )) ||
9038                 error "(3) lfs find expected 2 files, got $nfiles"
9039
9040         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9041         [[ $err_msg =~ "No such file or directory" ]] ||
9042                 error "expected standard error message, got: '$err_msg'"
9043 }
9044 run_test 56ef "lfs find with multiple paths"
9045
9046 test_56eg() {
9047         local dir=$DIR/$tdir
9048         local found
9049
9050         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9051
9052         test_mkdir -p $dir
9053
9054         touch $dir/$tfile
9055         ln -s $dir/$tfile $dir/$tfile.symlink
9056         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9057         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9058                 $dir/$tfile.symlink
9059         setfattr --no-dereference -n "trusted.common" \
9060                 $dir/{$tfile,$tfile.symlink}
9061
9062         found=$($LFS find -xattr "trusted.*=test_target" \
9063                 -xattr "trusted.common" $dir)
9064         [[ "$found" == "$dir/$tfile" ]] || {
9065                 getfattr -d -m trusted.* $dir/$tfile
9066                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9067         }
9068
9069         found=$($LFS find -xattr "trusted.*=test_link" \
9070                 -xattr "trusted.common" $dir)
9071         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9072                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9073                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9074         }
9075
9076         rm -f $dir/*
9077
9078         touch $dir/$tfile.1
9079         touch $dir/$tfile.2
9080         setfattr -n "user.test" -v "1" $dir/$tfile.1
9081         setfattr -n "user.test" -v "2" $dir/$tfile.2
9082         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9083
9084         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9085         [[ "$found" == "$dir/$tfile.1" ]] || {
9086                 getfattr -d $dir/$tfile.1
9087                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9088         }
9089
9090         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9091         [[ "$found" == "$dir/$tfile.2" ]] || {
9092                 getfattr -d $dir/$tfile.2
9093                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9094         }
9095
9096         setfattr -n "user.empty" $dir/$tfile.1
9097         found=$($LFS find -xattr "user.empty" $dir)
9098         [[ "$found" == "$dir/$tfile.1" ]] || {
9099                 getfattr -d $dir/$tfile.1
9100                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9101         }
9102
9103         # setfattr command normally does not store terminating null byte
9104         # when writing a string as an xattr value.
9105         #
9106         # In order to test matching a value string that includes a terminating
9107         # null, explicitly encode the string "test\0" with the null terminator.
9108         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9109         found=$($LFS find -xattr "user.test=test" $dir)
9110         [[ "$found" == "$dir/$tfile.1" ]] || {
9111                 getfattr -d --encoding=hex $dir/$tfile.1
9112                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9113         }
9114 }
9115 run_test 56eg "lfs find -xattr"
9116
9117 test_57a() {
9118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9119         # note test will not do anything if MDS is not local
9120         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9121                 skip_env "ldiskfs only test"
9122         fi
9123         remote_mds_nodsh && skip "remote MDS with nodsh"
9124
9125         local MNTDEV="osd*.*MDT*.mntdev"
9126         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9127         [ -z "$DEV" ] && error "can't access $MNTDEV"
9128         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9129                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9130                         error "can't access $DEV"
9131                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9132                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9133                 rm $TMP/t57a.dump
9134         done
9135 }
9136 run_test 57a "verify MDS filesystem created with large inodes =="
9137
9138 test_57b() {
9139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9140         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9141                 skip_env "ldiskfs only test"
9142         fi
9143         remote_mds_nodsh && skip "remote MDS with nodsh"
9144
9145         local dir=$DIR/$tdir
9146         local filecount=100
9147         local file1=$dir/f1
9148         local fileN=$dir/f$filecount
9149
9150         rm -rf $dir || error "removing $dir"
9151         test_mkdir -c1 $dir
9152         local mdtidx=$($LFS getstripe -m $dir)
9153         local mdtname=MDT$(printf %04x $mdtidx)
9154         local facet=mds$((mdtidx + 1))
9155
9156         echo "mcreating $filecount files"
9157         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9158
9159         # verify that files do not have EAs yet
9160         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9161                 error "$file1 has an EA"
9162         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9163                 error "$fileN has an EA"
9164
9165         sync
9166         sleep 1
9167         df $dir  #make sure we get new statfs data
9168         local mdsfree=$(do_facet $facet \
9169                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9170         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9171         local file
9172
9173         echo "opening files to create objects/EAs"
9174         for file in $(seq -f $dir/f%g 1 $filecount); do
9175                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9176                         error "opening $file"
9177         done
9178
9179         # verify that files have EAs now
9180         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9181                 error "$file1 missing EA"
9182         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9183                 error "$fileN missing EA"
9184
9185         sleep 1  #make sure we get new statfs data
9186         df $dir
9187         local mdsfree2=$(do_facet $facet \
9188                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9189         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9190
9191         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9192                 if [ "$mdsfree" != "$mdsfree2" ]; then
9193                         error "MDC before $mdcfree != after $mdcfree2"
9194                 else
9195                         echo "MDC before $mdcfree != after $mdcfree2"
9196                         echo "unable to confirm if MDS has large inodes"
9197                 fi
9198         fi
9199         rm -rf $dir
9200 }
9201 run_test 57b "default LOV EAs are stored inside large inodes ==="
9202
9203 test_58() {
9204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9205         [ -z "$(which wiretest 2>/dev/null)" ] &&
9206                         skip_env "could not find wiretest"
9207
9208         wiretest
9209 }
9210 run_test 58 "verify cross-platform wire constants =============="
9211
9212 test_59() {
9213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9214
9215         echo "touch 130 files"
9216         createmany -o $DIR/f59- 130
9217         echo "rm 130 files"
9218         unlinkmany $DIR/f59- 130
9219         sync
9220         # wait for commitment of removal
9221         wait_delete_completed
9222 }
9223 run_test 59 "verify cancellation of llog records async ========="
9224
9225 TEST60_HEAD="test_60 run $RANDOM"
9226 test_60a() {
9227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9228         remote_mgs_nodsh && skip "remote MGS with nodsh"
9229         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9230                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9231                         skip_env "missing subtest run-llog.sh"
9232
9233         log "$TEST60_HEAD - from kernel mode"
9234         do_facet mgs "$LCTL dk > /dev/null"
9235         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9236         do_facet mgs $LCTL dk > $TMP/$tfile
9237
9238         # LU-6388: test llog_reader
9239         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9240         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9241         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9242                         skip_env "missing llog_reader"
9243         local fstype=$(facet_fstype mgs)
9244         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9245                 skip_env "Only for ldiskfs or zfs type mgs"
9246
9247         local mntpt=$(facet_mntpt mgs)
9248         local mgsdev=$(mgsdevname 1)
9249         local fid_list
9250         local fid
9251         local rec_list
9252         local rec
9253         local rec_type
9254         local obj_file
9255         local path
9256         local seq
9257         local oid
9258         local pass=true
9259
9260         #get fid and record list
9261         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9262                 tail -n 4))
9263         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9264                 tail -n 4))
9265         #remount mgs as ldiskfs or zfs type
9266         stop mgs || error "stop mgs failed"
9267         mount_fstype mgs || error "remount mgs failed"
9268         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9269                 fid=${fid_list[i]}
9270                 rec=${rec_list[i]}
9271                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9272                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9273                 oid=$((16#$oid))
9274
9275                 case $fstype in
9276                         ldiskfs )
9277                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9278                         zfs )
9279                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9280                 esac
9281                 echo "obj_file is $obj_file"
9282                 do_facet mgs $llog_reader $obj_file
9283
9284                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9285                         awk '{ print $3 }' | sed -e "s/^type=//g")
9286                 if [ $rec_type != $rec ]; then
9287                         echo "FAILED test_60a wrong record type $rec_type," \
9288                               "should be $rec"
9289                         pass=false
9290                         break
9291                 fi
9292
9293                 #check obj path if record type is LLOG_LOGID_MAGIC
9294                 if [ "$rec" == "1064553b" ]; then
9295                         path=$(do_facet mgs $llog_reader $obj_file |
9296                                 grep "path=" | awk '{ print $NF }' |
9297                                 sed -e "s/^path=//g")
9298                         if [ $obj_file != $mntpt/$path ]; then
9299                                 echo "FAILED test_60a wrong obj path" \
9300                                       "$montpt/$path, should be $obj_file"
9301                                 pass=false
9302                                 break
9303                         fi
9304                 fi
9305         done
9306         rm -f $TMP/$tfile
9307         #restart mgs before "error", otherwise it will block the next test
9308         stop mgs || error "stop mgs failed"
9309         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9310         $pass || error "test failed, see FAILED test_60a messages for specifics"
9311 }
9312 run_test 60a "llog_test run from kernel module and test llog_reader"
9313
9314 test_60b() { # bug 6411
9315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9316
9317         dmesg > $DIR/$tfile
9318         LLOG_COUNT=$(do_facet mgs dmesg |
9319                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9320                           /llog_[a-z]*.c:[0-9]/ {
9321                                 if (marker)
9322                                         from_marker++
9323                                 from_begin++
9324                           }
9325                           END {
9326                                 if (marker)
9327                                         print from_marker
9328                                 else
9329                                         print from_begin
9330                           }")
9331
9332         [[ $LLOG_COUNT -gt 120 ]] &&
9333                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9334 }
9335 run_test 60b "limit repeated messages from CERROR/CWARN"
9336
9337 test_60c() {
9338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9339
9340         echo "create 5000 files"
9341         createmany -o $DIR/f60c- 5000
9342 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9343         lctl set_param fail_loc=0x80000137
9344         unlinkmany $DIR/f60c- 5000
9345         lctl set_param fail_loc=0
9346 }
9347 run_test 60c "unlink file when mds full"
9348
9349 test_60d() {
9350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9351
9352         SAVEPRINTK=$(lctl get_param -n printk)
9353         # verify "lctl mark" is even working"
9354         MESSAGE="test message ID $RANDOM $$"
9355         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9356         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9357
9358         lctl set_param printk=0 || error "set lnet.printk failed"
9359         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9360         MESSAGE="new test message ID $RANDOM $$"
9361         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9362         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9363         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9364
9365         lctl set_param -n printk="$SAVEPRINTK"
9366 }
9367 run_test 60d "test printk console message masking"
9368
9369 test_60e() {
9370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9371         remote_mds_nodsh && skip "remote MDS with nodsh"
9372
9373         touch $DIR/$tfile
9374 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9375         do_facet mds1 lctl set_param fail_loc=0x15b
9376         rm $DIR/$tfile
9377 }
9378 run_test 60e "no space while new llog is being created"
9379
9380 test_60f() {
9381         local old_path=$($LCTL get_param -n debug_path)
9382
9383         stack_trap "$LCTL set_param debug_path=$old_path"
9384         stack_trap "rm -f $TMP/$tfile*"
9385         rm -f $TMP/$tfile* 2> /dev/null
9386         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9387         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9388         test_mkdir $DIR/$tdir
9389         # retry in case the open is cached and not released
9390         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9391                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9392                 sleep 0.1
9393         done
9394         ls $TMP/$tfile*
9395         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9396 }
9397 run_test 60f "change debug_path works"
9398
9399 test_60g() {
9400         local pid
9401         local i
9402
9403         test_mkdir -c $MDSCOUNT $DIR/$tdir
9404
9405         (
9406                 local index=0
9407                 while true; do
9408                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9409                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9410                                 2>/dev/null
9411                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9412                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9413                         index=$((index + 1))
9414                 done
9415         ) &
9416
9417         pid=$!
9418
9419         for i in {0..100}; do
9420                 # define OBD_FAIL_OSD_TXN_START    0x19a
9421                 local index=$((i % MDSCOUNT + 1))
9422
9423                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9424                         > /dev/null
9425                 sleep 0.01
9426         done
9427
9428         kill -9 $pid
9429
9430         for i in $(seq $MDSCOUNT); do
9431                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9432         done
9433
9434         mkdir $DIR/$tdir/new || error "mkdir failed"
9435         rmdir $DIR/$tdir/new || error "rmdir failed"
9436
9437         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9438                 -t namespace
9439         for i in $(seq $MDSCOUNT); do
9440                 wait_update_facet mds$i "$LCTL get_param -n \
9441                         mdd.$(facet_svc mds$i).lfsck_namespace |
9442                         awk '/^status/ { print \\\$2 }'" "completed"
9443         done
9444
9445         ls -R $DIR/$tdir
9446         rm -rf $DIR/$tdir || error "rmdir failed"
9447 }
9448 run_test 60g "transaction abort won't cause MDT hung"
9449
9450 test_60h() {
9451         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9452                 skip "Need MDS version at least 2.12.52"
9453         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9454
9455         local f
9456
9457         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9458         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9459         for fail_loc in 0x80000188 0x80000189; do
9460                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9461                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9462                         error "mkdir $dir-$fail_loc failed"
9463                 for i in {0..10}; do
9464                         # create may fail on missing stripe
9465                         echo $i > $DIR/$tdir-$fail_loc/$i
9466                 done
9467                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9468                         error "getdirstripe $tdir-$fail_loc failed"
9469                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9470                         error "migrate $tdir-$fail_loc failed"
9471                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9472                         error "getdirstripe $tdir-$fail_loc failed"
9473                 pushd $DIR/$tdir-$fail_loc
9474                 for f in *; do
9475                         echo $f | cmp $f - || error "$f data mismatch"
9476                 done
9477                 popd
9478                 rm -rf $DIR/$tdir-$fail_loc
9479         done
9480 }
9481 run_test 60h "striped directory with missing stripes can be accessed"
9482
9483 function t60i_load() {
9484         mkdir $DIR/$tdir
9485         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9486         $LCTL set_param fail_loc=0x131c fail_val=1
9487         for ((i=0; i<5000; i++)); do
9488                 touch $DIR/$tdir/f$i
9489         done
9490 }
9491
9492 test_60i() {
9493         changelog_register || error "changelog_register failed"
9494         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9495         changelog_users $SINGLEMDS | grep -q $cl_user ||
9496                 error "User $cl_user not found in changelog_users"
9497         changelog_chmask "ALL"
9498         t60i_load &
9499         local PID=$!
9500         for((i=0; i<100; i++)); do
9501                 changelog_dump >/dev/null ||
9502                         error "can't read changelog"
9503         done
9504         kill $PID
9505         wait $PID
9506         changelog_deregister || error "changelog_deregister failed"
9507         $LCTL set_param fail_loc=0
9508 }
9509 run_test 60i "llog: new record vs reader race"
9510
9511 test_60j() {
9512         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9513                 skip "need MDS version at least 2.15.50"
9514         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9515         remote_mds_nodsh && skip "remote MDS with nodsh"
9516         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9517
9518         changelog_users $SINGLEMDS | grep "^cl" &&
9519                 skip "active changelog user"
9520
9521         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9522
9523         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9524                 skip_env "missing llog_reader"
9525
9526         mkdir_on_mdt0 $DIR/$tdir
9527
9528         local f=$DIR/$tdir/$tfile
9529         local mdt_dev
9530         local tmpfile
9531         local plain
9532
9533         changelog_register || error "cannot register changelog user"
9534
9535         # set changelog_mask to ALL
9536         changelog_chmask "ALL"
9537         changelog_clear
9538
9539         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9540         unlinkmany ${f}- 100 || error "unlinkmany failed"
9541
9542         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9543         mdt_dev=$(facet_device $SINGLEMDS)
9544
9545         do_facet $SINGLEMDS sync
9546         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9547                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9548                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9549
9550         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9551
9552         # if $tmpfile is not on EXT3 filesystem for some reason
9553         [[ ${plain:0:1} == 'O' ]] ||
9554                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9555
9556         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9557                 $mdt_dev; stat -c %s $tmpfile")
9558         echo "Truncate llog from $size to $((size - size % 8192))"
9559         size=$((size - size % 8192))
9560         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9561         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9562                 grep -c 'in bitmap only')
9563         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9564
9565         size=$((size - 9000))
9566         echo "Corrupt llog in the middle at $size"
9567         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9568                 count=333 conv=notrunc
9569         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9570                 grep -c 'next chunk')
9571         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9572 }
9573 run_test 60j "llog_reader reports corruptions"
9574
9575 test_61a() {
9576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9577
9578         f="$DIR/f61"
9579         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9580         cancel_lru_locks osc
9581         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9582         sync
9583 }
9584 run_test 61a "mmap() writes don't make sync hang ================"
9585
9586 test_61b() {
9587         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9588 }
9589 run_test 61b "mmap() of unstriped file is successful"
9590
9591 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9592 # Though this test is irrelevant anymore, it helped to reveal some
9593 # other grant bugs (LU-4482), let's keep it.
9594 test_63a() {   # was test_63
9595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9596
9597         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9598
9599         for i in `seq 10` ; do
9600                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9601                 sleep 5
9602                 kill $!
9603                 sleep 1
9604         done
9605
9606         rm -f $DIR/f63 || true
9607 }
9608 run_test 63a "Verify oig_wait interruption does not crash ======="
9609
9610 # bug 2248 - async write errors didn't return to application on sync
9611 # bug 3677 - async write errors left page locked
9612 test_63b() {
9613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9614
9615         debugsave
9616         lctl set_param debug=-1
9617
9618         # ensure we have a grant to do async writes
9619         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9620         rm $DIR/$tfile
9621
9622         sync    # sync lest earlier test intercept the fail_loc
9623
9624         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9625         lctl set_param fail_loc=0x80000406
9626         $MULTIOP $DIR/$tfile Owy && \
9627                 error "sync didn't return ENOMEM"
9628         sync; sleep 2; sync     # do a real sync this time to flush page
9629         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9630                 error "locked page left in cache after async error" || true
9631         debugrestore
9632 }
9633 run_test 63b "async write errors should be returned to fsync ==="
9634
9635 test_64a () {
9636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9637
9638         lfs df $DIR
9639         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9640 }
9641 run_test 64a "verify filter grant calculations (in kernel) ====="
9642
9643 test_64b () {
9644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9645
9646         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9647 }
9648 run_test 64b "check out-of-space detection on client"
9649
9650 test_64c() {
9651         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9652 }
9653 run_test 64c "verify grant shrink"
9654
9655 import_param() {
9656         local tgt=$1
9657         local param=$2
9658
9659         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9660 }
9661
9662 # this does exactly what osc_request.c:osc_announce_cached() does in
9663 # order to calculate max amount of grants to ask from server
9664 want_grant() {
9665         local tgt=$1
9666
9667         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9668         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9669
9670         ((rpc_in_flight++));
9671         nrpages=$((nrpages * rpc_in_flight))
9672
9673         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9674
9675         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9676
9677         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9678         local undirty=$((nrpages * PAGE_SIZE))
9679
9680         local max_extent_pages
9681         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9682         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9683         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9684         local grant_extent_tax
9685         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9686
9687         undirty=$((undirty + nrextents * grant_extent_tax))
9688
9689         echo $undirty
9690 }
9691
9692 # this is size of unit for grant allocation. It should be equal to
9693 # what tgt_grant.c:tgt_grant_chunk() calculates
9694 grant_chunk() {
9695         local tgt=$1
9696         local max_brw_size
9697         local grant_extent_tax
9698
9699         max_brw_size=$(import_param $tgt max_brw_size)
9700
9701         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9702
9703         echo $(((max_brw_size + grant_extent_tax) * 2))
9704 }
9705
9706 test_64d() {
9707         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9708                 skip "OST < 2.10.55 doesn't limit grants enough"
9709
9710         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9711
9712         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9713                 skip "no grant_param connect flag"
9714
9715         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9716
9717         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9718         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9719
9720
9721         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9722         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9723
9724         $LFS setstripe $DIR/$tfile -i 0 -c 1
9725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9726         ddpid=$!
9727
9728         while kill -0 $ddpid; do
9729                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9730
9731                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9732                         kill $ddpid
9733                         error "cur_grant $cur_grant > $max_cur_granted"
9734                 fi
9735
9736                 sleep 1
9737         done
9738 }
9739 run_test 64d "check grant limit exceed"
9740
9741 check_grants() {
9742         local tgt=$1
9743         local expected=$2
9744         local msg=$3
9745         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9746
9747         ((cur_grants == expected)) ||
9748                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9749 }
9750
9751 round_up_p2() {
9752         echo $((($1 + $2 - 1) & ~($2 - 1)))
9753 }
9754
9755 test_64e() {
9756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9757         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9758                 skip "Need OSS version at least 2.11.56"
9759
9760         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9761         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9762         $LCTL set_param debug=+cache
9763
9764         # Remount client to reset grant
9765         remount_client $MOUNT || error "failed to remount client"
9766         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9767
9768         local init_grants=$(import_param $osc_tgt initial_grant)
9769
9770         check_grants $osc_tgt $init_grants "init grants"
9771
9772         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9773         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9774         local gbs=$(import_param $osc_tgt grant_block_size)
9775
9776         # write random number of bytes from max_brw_size / 4 to max_brw_size
9777         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9778         # align for direct io
9779         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9780         # round to grant consumption unit
9781         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9782
9783         local grants=$((wb_round_up + extent_tax))
9784
9785         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9786         stack_trap "rm -f $DIR/$tfile"
9787
9788         # define OBD_FAIL_TGT_NO_GRANT 0x725
9789         # make the server not grant more back
9790         do_facet ost1 $LCTL set_param fail_loc=0x725
9791         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9792
9793         do_facet ost1 $LCTL set_param fail_loc=0
9794
9795         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9796
9797         rm -f $DIR/$tfile || error "rm failed"
9798
9799         # Remount client to reset grant
9800         remount_client $MOUNT || error "failed to remount client"
9801         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9802
9803         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9804
9805         # define OBD_FAIL_TGT_NO_GRANT 0x725
9806         # make the server not grant more back
9807         do_facet ost1 $LCTL set_param fail_loc=0x725
9808         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9809         do_facet ost1 $LCTL set_param fail_loc=0
9810
9811         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9812 }
9813 run_test 64e "check grant consumption (no grant allocation)"
9814
9815 test_64f() {
9816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9817
9818         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9819         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9820         $LCTL set_param debug=+cache
9821
9822         # Remount client to reset grant
9823         remount_client $MOUNT || error "failed to remount client"
9824         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9825
9826         local init_grants=$(import_param $osc_tgt initial_grant)
9827         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9828         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9829         local gbs=$(import_param $osc_tgt grant_block_size)
9830         local chunk=$(grant_chunk $osc_tgt)
9831
9832         # write random number of bytes from max_brw_size / 4 to max_brw_size
9833         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9834         # align for direct io
9835         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9836         # round to grant consumption unit
9837         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9838
9839         local grants=$((wb_round_up + extent_tax))
9840
9841         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9842         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9843                 error "error writing to $DIR/$tfile"
9844
9845         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9846                 "direct io with grant allocation"
9847
9848         rm -f $DIR/$tfile || error "rm failed"
9849
9850         # Remount client to reset grant
9851         remount_client $MOUNT || error "failed to remount client"
9852         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9853
9854         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9855
9856         # Testing that buffered IO consumes grant on the client
9857
9858         # Delay the RPC on the server so it's guaranteed to not complete even
9859         # if the RPC is sent from the client
9860         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9861         $LCTL set_param fail_loc=0x50a fail_val=3
9862         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9863                 error "error writing to $DIR/$tfile with buffered IO"
9864
9865         check_grants $osc_tgt $((init_grants - grants)) \
9866                 "buffered io, not write rpc"
9867
9868         # Clear the fail loc and do a sync on the client
9869         $LCTL set_param fail_loc=0 fail_val=0
9870         sync
9871
9872         # RPC is now known to have sent
9873         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9874                 "buffered io, one RPC"
9875 }
9876 run_test 64f "check grant consumption (with grant allocation)"
9877
9878 test_64g() {
9879         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9880                 skip "Need MDS version at least 2.14.56"
9881
9882         local mdts=$(comma_list $(mdts_nodes))
9883
9884         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9885                         tr '\n' ' ')
9886         stack_trap "$LCTL set_param $old"
9887
9888         # generate dirty pages and increase dirty granted on MDT
9889         stack_trap "rm -f $DIR/$tfile-*"
9890         for (( i = 0; i < 10; i++)); do
9891                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9892                         error "can't set stripe"
9893                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9894                         error "can't dd"
9895                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9896                         $LFS getstripe $DIR/$tfile-$i
9897                         error "not DoM file"
9898                 }
9899         done
9900
9901         # flush dirty pages
9902         sync
9903
9904         # wait until grant shrink reset grant dirty on MDTs
9905         for ((i = 0; i < 120; i++)); do
9906                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9907                         awk '{sum=sum+$1} END {print sum}')
9908                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9909                 echo "$grant_dirty grants, $vm_dirty pages"
9910                 (( grant_dirty + vm_dirty == 0 )) && break
9911                 (( i == 3 )) && sync &&
9912                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9913                 sleep 1
9914         done
9915
9916         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9917                 awk '{sum=sum+$1} END {print sum}')
9918         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9919 }
9920 run_test 64g "grant shrink on MDT"
9921
9922 test_64h() {
9923         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9924                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9925
9926         local instance=$($LFS getname -i $DIR)
9927         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9928         local num_exps=$(do_facet ost1 \
9929             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9930         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9931         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9932         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9933
9934         # 10MiB is for file to be written, max_brw_size * 16 *
9935         # num_exps is space reserve so that tgt_grant_shrink() decided
9936         # to not shrink
9937         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9938         (( avail * 1024 < expect )) &&
9939                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9940
9941         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9942         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9943         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9944         $LCTL set_param osc.*OST0000*.grant_shrink=1
9945         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9946
9947         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9948         stack_trap "rm -f $DIR/$tfile"
9949         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9950
9951         # drop cache so that coming read would do rpc
9952         cancel_lru_locks osc
9953
9954         # shrink interval is set to 10, pause for 7 seconds so that
9955         # grant thread did not wake up yet but coming read entered
9956         # shrink mode for rpc (osc_should_shrink_grant())
9957         sleep 7
9958
9959         declare -a cur_grant_bytes
9960         declare -a tot_granted
9961         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9962         tot_granted[0]=$(do_facet ost1 \
9963             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9964
9965         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9966
9967         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9968         tot_granted[1]=$(do_facet ost1 \
9969             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9970
9971         # grant change should be equal on both sides
9972         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9973                 tot_granted[0] - tot_granted[1])) ||
9974                 error "grant change mismatch, "                                \
9975                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9976                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9977 }
9978 run_test 64h "grant shrink on read"
9979
9980 test_64i() {
9981         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9982                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9983
9984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9985         remote_ost_nodsh && skip "remote OSTs with nodsh"
9986
9987         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9988         stack_trap "rm -f $DIR/$tfile"
9989
9990         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9991
9992         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9993         local instance=$($LFS getname -i $DIR)
9994
9995         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9996         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9997
9998         # shrink grants and simulate rpc loss
9999         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10000         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10001         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10002
10003         fail ost1
10004
10005         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10006
10007         local testid=$(echo $TESTNAME | tr '_' ' ')
10008
10009         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10010                 grep "GRANT, real grant" &&
10011                 error "client has more grants then it owns" || true
10012 }
10013 run_test 64i "shrink on reconnect"
10014
10015 # bug 1414 - set/get directories' stripe info
10016 test_65a() {
10017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10018
10019         # LU-16904 check if the root is set as PFL layout
10020         local numcomp=$($LFS getstripe --component-count $MOUNT)
10021         [ $numcomp -eq 0 ] || skip "Skip test_65a for PFL layout"
10022
10023         test_mkdir $DIR/$tdir
10024         touch $DIR/$tdir/f1
10025         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10026 }
10027 run_test 65a "directory with no stripe info"
10028
10029 test_65b() {
10030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10031
10032         test_mkdir $DIR/$tdir
10033         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10034
10035         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10036                                                 error "setstripe"
10037         touch $DIR/$tdir/f2
10038         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10039 }
10040 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10041
10042 test_65c() {
10043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10044         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10045
10046         test_mkdir $DIR/$tdir
10047         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10048
10049         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10050                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10051         touch $DIR/$tdir/f3
10052         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10053 }
10054 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10055
10056 test_65d() {
10057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10058
10059         test_mkdir $DIR/$tdir
10060         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10061         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10062
10063         if [[ $STRIPECOUNT -le 0 ]]; then
10064                 sc=1
10065         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10066                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10067                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10068         else
10069                 sc=$(($STRIPECOUNT - 1))
10070         fi
10071         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10072         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10073         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10074                 error "lverify failed"
10075 }
10076 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10077
10078 test_65e() {
10079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10080
10081         # LU-16904 delete layout when root is set as PFL layout
10082         save_layout_restore_at_exit $MOUNT
10083         $LFS setstripe -d $MOUNT || error "setstripe failed"
10084
10085         test_mkdir $DIR/$tdir
10086
10087         $LFS setstripe $DIR/$tdir || error "setstripe"
10088         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10089                                         error "no stripe info failed"
10090         touch $DIR/$tdir/f6
10091         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10092 }
10093 run_test 65e "directory setstripe defaults"
10094
10095 test_65f() {
10096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10097
10098         test_mkdir $DIR/${tdir}f
10099         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10100                 error "setstripe succeeded" || true
10101 }
10102 run_test 65f "dir setstripe permission (should return error) ==="
10103
10104 test_65g() {
10105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10106
10107         # LU-16904 delete layout when root is set as PFL layout
10108         save_layout_restore_at_exit $MOUNT
10109         $LFS setstripe -d $MOUNT || error "setstripe failed"
10110
10111         test_mkdir $DIR/$tdir
10112         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10113
10114         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10115                 error "setstripe -S failed"
10116         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10117         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10118                 error "delete default stripe failed"
10119 }
10120 run_test 65g "directory setstripe -d"
10121
10122 test_65h() {
10123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10124
10125         test_mkdir $DIR/$tdir
10126         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10127
10128         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10129                 error "setstripe -S failed"
10130         test_mkdir $DIR/$tdir/dd1
10131         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10132                 error "stripe info inherit failed"
10133 }
10134 run_test 65h "directory stripe info inherit ===================="
10135
10136 test_65i() {
10137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10138
10139         save_layout_restore_at_exit $MOUNT
10140
10141         # bug6367: set non-default striping on root directory
10142         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10143
10144         # bug12836: getstripe on -1 default directory striping
10145         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10146
10147         # bug12836: getstripe -v on -1 default directory striping
10148         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10149
10150         # bug12836: new find on -1 default directory striping
10151         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10152 }
10153 run_test 65i "various tests to set root directory striping"
10154
10155 test_65j() { # bug6367
10156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10157
10158         sync; sleep 1
10159
10160         # if we aren't already remounting for each test, do so for this test
10161         if [ "$I_MOUNTED" = "yes" ]; then
10162                 cleanup || error "failed to unmount"
10163                 setup
10164         fi
10165
10166         save_layout_restore_at_exit $MOUNT
10167
10168         $LFS setstripe -d $MOUNT || error "setstripe failed"
10169 }
10170 run_test 65j "set default striping on root directory (bug 6367)="
10171
10172 cleanup_65k() {
10173         rm -rf $DIR/$tdir
10174         wait_delete_completed
10175         do_facet $SINGLEMDS "lctl set_param -n \
10176                 osp.$ost*MDT0000.max_create_count=$max_count"
10177         do_facet $SINGLEMDS "lctl set_param -n \
10178                 osp.$ost*MDT0000.create_count=$count"
10179         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10180         echo $INACTIVE_OSC "is Activate"
10181
10182         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10183 }
10184
10185 test_65k() { # bug11679
10186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10187         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10188         remote_mds_nodsh && skip "remote MDS with nodsh"
10189
10190         local disable_precreate=true
10191         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10192                 disable_precreate=false
10193
10194         echo "Check OST status: "
10195         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10196                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10197
10198         for OSC in $MDS_OSCS; do
10199                 echo $OSC "is active"
10200                 do_facet $SINGLEMDS lctl --device %$OSC activate
10201         done
10202
10203         for INACTIVE_OSC in $MDS_OSCS; do
10204                 local ost=$(osc_to_ost $INACTIVE_OSC)
10205                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10206                                lov.*md*.target_obd |
10207                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10208
10209                 mkdir -p $DIR/$tdir
10210                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10211                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10212
10213                 echo "Deactivate: " $INACTIVE_OSC
10214                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10215
10216                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10217                               osp.$ost*MDT0000.create_count")
10218                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10219                                   osp.$ost*MDT0000.max_create_count")
10220                 $disable_precreate &&
10221                         do_facet $SINGLEMDS "lctl set_param -n \
10222                                 osp.$ost*MDT0000.max_create_count=0"
10223
10224                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10225                         [ -f $DIR/$tdir/$idx ] && continue
10226                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10227                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10228                                 { cleanup_65k;
10229                                   error "setstripe $idx should succeed"; }
10230                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10231                 done
10232                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10233                 rmdir $DIR/$tdir
10234
10235                 do_facet $SINGLEMDS "lctl set_param -n \
10236                         osp.$ost*MDT0000.max_create_count=$max_count"
10237                 do_facet $SINGLEMDS "lctl set_param -n \
10238                         osp.$ost*MDT0000.create_count=$count"
10239                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10240                 echo $INACTIVE_OSC "is Activate"
10241
10242                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10243         done
10244 }
10245 run_test 65k "validate manual striping works properly with deactivated OSCs"
10246
10247 test_65l() { # bug 12836
10248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10249
10250         test_mkdir -p $DIR/$tdir/test_dir
10251         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10252         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10253 }
10254 run_test 65l "lfs find on -1 stripe dir ========================"
10255
10256 test_65m() {
10257         local layout=$(save_layout $MOUNT)
10258         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10259                 restore_layout $MOUNT $layout
10260                 error "setstripe should fail by non-root users"
10261         }
10262         true
10263 }
10264 run_test 65m "normal user can't set filesystem default stripe"
10265
10266 test_65n() {
10267         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10268         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10269                 skip "Need MDS version at least 2.12.50"
10270         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10271
10272         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10273         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10274         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10275
10276         save_layout_restore_at_exit $MOUNT
10277
10278         # new subdirectory under root directory should not inherit
10279         # the default layout from root
10280         # LU-16904 check if the root is set as PFL layout
10281         local numcomp=$($LFS getstripe --component-count $MOUNT)
10282
10283         if [[ $numcomp -eq 0 ]]; then
10284                 local dir1=$MOUNT/$tdir-1
10285                 mkdir $dir1 || error "mkdir $dir1 failed"
10286                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10287                         error "$dir1 shouldn't have LOV EA"
10288         fi
10289
10290         # delete the default layout on root directory
10291         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10292
10293         local dir2=$MOUNT/$tdir-2
10294         mkdir $dir2 || error "mkdir $dir2 failed"
10295         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10296                 error "$dir2 shouldn't have LOV EA"
10297
10298         # set a new striping pattern on root directory
10299         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10300         local new_def_stripe_size=$((def_stripe_size * 2))
10301         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10302                 error "set stripe size on $MOUNT failed"
10303
10304         # new file created in $dir2 should inherit the new stripe size from
10305         # the filesystem default
10306         local file2=$dir2/$tfile-2
10307         touch $file2 || error "touch $file2 failed"
10308
10309         local file2_stripe_size=$($LFS getstripe -S $file2)
10310         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10311         {
10312                 echo "file2_stripe_size: '$file2_stripe_size'"
10313                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10314                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10315         }
10316
10317         local dir3=$MOUNT/$tdir-3
10318         mkdir $dir3 || error "mkdir $dir3 failed"
10319         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10320         # the root layout, which is the actual default layout that will be used
10321         # when new files are created in $dir3.
10322         local dir3_layout=$(get_layout_param $dir3)
10323         local root_dir_layout=$(get_layout_param $MOUNT)
10324         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10325         {
10326                 echo "dir3_layout: '$dir3_layout'"
10327                 echo "root_dir_layout: '$root_dir_layout'"
10328                 error "$dir3 should show the default layout from $MOUNT"
10329         }
10330
10331         # set OST pool on root directory
10332         local pool=$TESTNAME
10333         pool_add $pool || error "add $pool failed"
10334         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10335                 error "add targets to $pool failed"
10336
10337         $LFS setstripe -p $pool $MOUNT ||
10338                 error "set OST pool on $MOUNT failed"
10339
10340         # new file created in $dir3 should inherit the pool from
10341         # the filesystem default
10342         local file3=$dir3/$tfile-3
10343         touch $file3 || error "touch $file3 failed"
10344
10345         local file3_pool=$($LFS getstripe -p $file3)
10346         [[ "$file3_pool" = "$pool" ]] ||
10347                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10348
10349         local dir4=$MOUNT/$tdir-4
10350         mkdir $dir4 || error "mkdir $dir4 failed"
10351         local dir4_layout=$(get_layout_param $dir4)
10352         root_dir_layout=$(get_layout_param $MOUNT)
10353         echo "$LFS getstripe -d $dir4"
10354         $LFS getstripe -d $dir4
10355         echo "$LFS getstripe -d $MOUNT"
10356         $LFS getstripe -d $MOUNT
10357         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10358         {
10359                 echo "dir4_layout: '$dir4_layout'"
10360                 echo "root_dir_layout: '$root_dir_layout'"
10361                 error "$dir4 should show the default layout from $MOUNT"
10362         }
10363
10364         # new file created in $dir4 should inherit the pool from
10365         # the filesystem default
10366         local file4=$dir4/$tfile-4
10367         touch $file4 || error "touch $file4 failed"
10368
10369         local file4_pool=$($LFS getstripe -p $file4)
10370         [[ "$file4_pool" = "$pool" ]] ||
10371                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10372
10373         # new subdirectory under non-root directory should inherit
10374         # the default layout from its parent directory
10375         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10376                 error "set directory layout on $dir4 failed"
10377
10378         local dir5=$dir4/$tdir-5
10379         mkdir $dir5 || error "mkdir $dir5 failed"
10380
10381         dir4_layout=$(get_layout_param $dir4)
10382         local dir5_layout=$(get_layout_param $dir5)
10383         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10384         {
10385                 echo "dir4_layout: '$dir4_layout'"
10386                 echo "dir5_layout: '$dir5_layout'"
10387                 error "$dir5 should inherit the default layout from $dir4"
10388         }
10389
10390         # though subdir under ROOT doesn't inherit default layout, but
10391         # its sub dir/file should be created with default layout.
10392         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10393         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10394                 skip "Need MDS version at least 2.12.59"
10395
10396         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10397         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10398         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10399
10400         if [ $default_lmv_hash == "none" ]; then
10401                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10402         else
10403                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10404                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10405         fi
10406
10407         $LFS setdirstripe -D -c 2 $MOUNT ||
10408                 error "setdirstripe -D -c 2 failed"
10409         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10410         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10411         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10412
10413         # $dir4 layout includes pool
10414         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10415         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10416                 error "pool lost on setstripe"
10417         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10418         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10419                 error "pool lost on compound layout setstripe"
10420 }
10421 run_test 65n "don't inherit default layout from root for new subdirectories"
10422
10423 test_65o() {
10424         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10425                 skip "need MDS version at least 2.14.57"
10426
10427         # set OST pool on root directory
10428         local pool=$TESTNAME
10429
10430         pool_add $pool || error "add $pool failed"
10431         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10432                 error "add targets to $pool failed"
10433
10434         local dir1=$MOUNT/$tdir
10435
10436         mkdir $dir1 || error "mkdir $dir1 failed"
10437
10438         # set a new striping pattern on root directory
10439         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10440
10441         $LFS setstripe -p $pool $dir1 ||
10442                 error "set directory layout on $dir1 failed"
10443
10444         # $dir1 layout includes pool
10445         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10446         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10447                 error "pool lost on setstripe"
10448         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10449         $LFS getstripe $dir1
10450         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10451                 error "pool lost on compound layout setstripe"
10452
10453         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10454                 error "setdirstripe failed on sub-dir with inherited pool"
10455         $LFS getstripe $dir1/dir2
10456         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10457                 error "pool lost on compound layout setdirstripe"
10458
10459         $LFS setstripe -E -1 -c 1 $dir1
10460         $LFS getstripe -d $dir1
10461         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10462                 error "pool lost on setstripe"
10463 }
10464 run_test 65o "pool inheritance for mdt component"
10465
10466 test_65p () { # LU-16152
10467         local src_dir=$DIR/$tdir/src_dir
10468         local dst_dir=$DIR/$tdir/dst_dir
10469         local yaml_file=$DIR/$tdir/layout.yaml
10470         local border
10471
10472         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10473                 skip "Need at least version 2.15.51"
10474
10475         test_mkdir -p $src_dir
10476         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10477                 error "failed to setstripe"
10478         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10479                 error "failed to getstripe"
10480
10481         test_mkdir -p $dst_dir
10482         $LFS setstripe --yaml $yaml_file $dst_dir ||
10483                 error "failed to setstripe with yaml file"
10484         border=$($LFS getstripe -d $dst_dir |
10485                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10486                 error "failed to getstripe"
10487
10488         # 2048M is 0x80000000, or 2147483648
10489         (( $border == 2147483648 )) ||
10490                 error "failed to handle huge number in yaml layout"
10491 }
10492 run_test 65p "setstripe with yaml file and huge number"
10493
10494 test_65q () { # LU-16194
10495         local src_dir=$DIR/$tdir/src_dir
10496
10497         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10498         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10499                 skip "Need at least version 2.15.51"
10500
10501         test_mkdir -p $src_dir
10502         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10503         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10504                 error "should fail if extent start/end >=8E"
10505
10506         # EOF should work as before
10507         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10508                 error "failed to setstripe normally"
10509 }
10510 run_test 65q "setstripe with >=8E offset should fail"
10511
10512 # bug 2543 - update blocks count on client
10513 test_66() {
10514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10515
10516         local COUNT=${COUNT:-8}
10517         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10518         sync; sync_all_data; sync; sync_all_data
10519         cancel_lru_locks osc
10520         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10521         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10522 }
10523 run_test 66 "update inode blocks count on client ==============="
10524
10525 meminfo() {
10526         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10527 }
10528
10529 swap_used() {
10530         swapon -s | awk '($1 == "'$1'") { print $4 }'
10531 }
10532
10533 # bug5265, obdfilter oa2dentry return -ENOENT
10534 # #define OBD_FAIL_SRV_ENOENT 0x217
10535 test_69() {
10536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10537         remote_ost_nodsh && skip "remote OST with nodsh"
10538
10539         f="$DIR/$tfile"
10540         $LFS setstripe -c 1 -i 0 $f
10541         stack_trap "rm -f $f ${f}.2"
10542
10543         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10544
10545         do_facet ost1 lctl set_param fail_loc=0x217
10546         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10547         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10548
10549         do_facet ost1 lctl set_param fail_loc=0
10550         $DIRECTIO write $f 0 2 || error "write error"
10551
10552         cancel_lru_locks osc
10553         $DIRECTIO read $f 0 1 || error "read error"
10554
10555         do_facet ost1 lctl set_param fail_loc=0x217
10556         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10557
10558         do_facet ost1 lctl set_param fail_loc=0
10559 }
10560 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10561
10562 test_70a() {
10563         # Perform a really simple test of health write and health check
10564         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10565                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10566
10567         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10568
10569         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10570
10571         # Test with health write off
10572         do_facet ost1 $LCTL set_param enable_health_write off ||
10573                 error "can't set enable_health_write off"
10574         do_facet ost1 $LCTL get_param enable_health_write ||
10575                 error "can't get enable_health_write"
10576
10577         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10578                 error "not healthy (1)"
10579
10580         # Test with health write on
10581         do_facet ost1 $LCTL set_param enable_health_write on ||
10582                 error "can't set enable_health_write on"
10583         do_facet ost1 $LCTL get_param enable_health_write ||
10584                 error "can't get enable_health_write"
10585
10586         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10587                 error "not healthy (2)"
10588 }
10589 run_test 70a "verify health_check, health_write don't explode (on OST)"
10590
10591 test_71() {
10592         test_mkdir $DIR/$tdir
10593         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10594         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10595 }
10596 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10597
10598 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10600         [ "$RUNAS_ID" = "$UID" ] &&
10601                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10602         # Check that testing environment is properly set up. Skip if not
10603         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10604                 skip_env "User $RUNAS_ID does not exist - skipping"
10605
10606         touch $DIR/$tfile
10607         chmod 777 $DIR/$tfile
10608         chmod ug+s $DIR/$tfile
10609         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10610                 error "$RUNAS dd $DIR/$tfile failed"
10611         # See if we are still setuid/sgid
10612         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10613                 error "S/gid is not dropped on write"
10614         # Now test that MDS is updated too
10615         cancel_lru_locks mdc
10616         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10617                 error "S/gid is not dropped on MDS"
10618         rm -f $DIR/$tfile
10619 }
10620 run_test 72a "Test that remove suid works properly (bug5695) ===="
10621
10622 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10623         local perm
10624
10625         [ "$RUNAS_ID" = "$UID" ] &&
10626                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10627         [ "$RUNAS_ID" -eq 0 ] &&
10628                 skip_env "RUNAS_ID = 0 -- skipping"
10629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10630         # Check that testing environment is properly set up. Skip if not
10631         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10632                 skip_env "User $RUNAS_ID does not exist - skipping"
10633
10634         touch $DIR/${tfile}-f{g,u}
10635         test_mkdir $DIR/${tfile}-dg
10636         test_mkdir $DIR/${tfile}-du
10637         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10638         chmod g+s $DIR/${tfile}-{f,d}g
10639         chmod u+s $DIR/${tfile}-{f,d}u
10640         for perm in 777 2777 4777; do
10641                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10642                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10643                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10644                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10645         done
10646         true
10647 }
10648 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10649
10650 # bug 3462 - multiple simultaneous MDC requests
10651 test_73() {
10652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10653
10654         test_mkdir $DIR/d73-1
10655         test_mkdir $DIR/d73-2
10656         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10657         pid1=$!
10658
10659         lctl set_param fail_loc=0x80000129
10660         $MULTIOP $DIR/d73-1/f73-2 Oc &
10661         sleep 1
10662         lctl set_param fail_loc=0
10663
10664         $MULTIOP $DIR/d73-2/f73-3 Oc &
10665         pid3=$!
10666
10667         kill -USR1 $pid1
10668         wait $pid1 || return 1
10669
10670         sleep 25
10671
10672         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10673         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10674         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10675
10676         rm -rf $DIR/d73-*
10677 }
10678 run_test 73 "multiple MDC requests (should not deadlock)"
10679
10680 test_74a() { # bug 6149, 6184
10681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10682
10683         touch $DIR/f74a
10684         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10685         #
10686         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10687         # will spin in a tight reconnection loop
10688         $LCTL set_param fail_loc=0x8000030e
10689         # get any lock that won't be difficult - lookup works.
10690         ls $DIR/f74a
10691         $LCTL set_param fail_loc=0
10692         rm -f $DIR/f74a
10693         true
10694 }
10695 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10696
10697 test_74b() { # bug 13310
10698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10699
10700         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10701         #
10702         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10703         # will spin in a tight reconnection loop
10704         $LCTL set_param fail_loc=0x8000030e
10705         # get a "difficult" lock
10706         touch $DIR/f74b
10707         $LCTL set_param fail_loc=0
10708         rm -f $DIR/f74b
10709         true
10710 }
10711 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10712
10713 test_74c() {
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715
10716         #define OBD_FAIL_LDLM_NEW_LOCK
10717         $LCTL set_param fail_loc=0x319
10718         touch $DIR/$tfile && error "touch successful"
10719         $LCTL set_param fail_loc=0
10720         true
10721 }
10722 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10723
10724 slab_lic=/sys/kernel/slab/lustre_inode_cache
10725 num_objects() {
10726         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10727         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10728                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10729 }
10730
10731 test_76a() { # Now for b=20433, added originally in b=1443
10732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10733
10734         cancel_lru_locks osc
10735         # there may be some slab objects cached per core
10736         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10737         local before=$(num_objects)
10738         local count=$((512 * cpus))
10739         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10740         local margin=$((count / 10))
10741         if [[ -f $slab_lic/aliases ]]; then
10742                 local aliases=$(cat $slab_lic/aliases)
10743                 (( aliases > 0 )) && margin=$((margin * aliases))
10744         fi
10745
10746         echo "before slab objects: $before"
10747         for i in $(seq $count); do
10748                 touch $DIR/$tfile
10749                 rm -f $DIR/$tfile
10750         done
10751         cancel_lru_locks osc
10752         local after=$(num_objects)
10753         echo "created: $count, after slab objects: $after"
10754         # shared slab counts are not very accurate, allow significant margin
10755         # the main goal is that the cache growth is not permanently > $count
10756         while (( after > before + margin )); do
10757                 sleep 1
10758                 after=$(num_objects)
10759                 wait=$((wait + 1))
10760                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10761                 if (( wait > 60 )); then
10762                         error "inode slab grew from $before+$margin to $after"
10763                 fi
10764         done
10765 }
10766 run_test 76a "confirm clients recycle inodes properly ===="
10767
10768 test_76b() {
10769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10770         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10771
10772         local count=512
10773         local before=$(num_objects)
10774
10775         for i in $(seq $count); do
10776                 mkdir $DIR/$tdir
10777                 rmdir $DIR/$tdir
10778         done
10779
10780         local after=$(num_objects)
10781         local wait=0
10782
10783         while (( after > before )); do
10784                 sleep 1
10785                 after=$(num_objects)
10786                 wait=$((wait + 1))
10787                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10788                 if (( wait > 60 )); then
10789                         error "inode slab grew from $before to $after"
10790                 fi
10791         done
10792
10793         echo "slab objects before: $before, after: $after"
10794 }
10795 run_test 76b "confirm clients recycle directory inodes properly ===="
10796
10797 export ORIG_CSUM=""
10798 set_checksums()
10799 {
10800         # Note: in sptlrpc modes which enable its own bulk checksum, the
10801         # original crc32_le bulk checksum will be automatically disabled,
10802         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10803         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10804         # In this case set_checksums() will not be no-op, because sptlrpc
10805         # bulk checksum will be enabled all through the test.
10806
10807         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10808         lctl set_param -n osc.*.checksums $1
10809         return 0
10810 }
10811
10812 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10813                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10814 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10815                              tr -d [] | head -n1)}
10816 set_checksum_type()
10817 {
10818         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10819         rc=$?
10820         log "set checksum type to $1, rc = $rc"
10821         return $rc
10822 }
10823
10824 get_osc_checksum_type()
10825 {
10826         # arugment 1: OST name, like OST0000
10827         ost=$1
10828         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10829                         sed 's/.*\[\(.*\)\].*/\1/g')
10830         rc=$?
10831         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10832         echo $checksum_type
10833 }
10834
10835 F77_TMP=$TMP/f77-temp
10836 F77SZ=8
10837 setup_f77() {
10838         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10839                 error "error writing to $F77_TMP"
10840 }
10841
10842 test_77a() { # bug 10889
10843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10844         $GSS && skip_env "could not run with gss"
10845
10846         [ ! -f $F77_TMP ] && setup_f77
10847         set_checksums 1
10848         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10849         set_checksums 0
10850         rm -f $DIR/$tfile
10851 }
10852 run_test 77a "normal checksum read/write operation"
10853
10854 test_77b() { # bug 10889
10855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10856         $GSS && skip_env "could not run with gss"
10857
10858         [ ! -f $F77_TMP ] && setup_f77
10859         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10860         $LCTL set_param fail_loc=0x80000409
10861         set_checksums 1
10862
10863         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10864                 error "dd error: $?"
10865         $LCTL set_param fail_loc=0
10866
10867         for algo in $CKSUM_TYPES; do
10868                 cancel_lru_locks osc
10869                 set_checksum_type $algo
10870                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10871                 $LCTL set_param fail_loc=0x80000408
10872                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10873                 $LCTL set_param fail_loc=0
10874         done
10875         set_checksums 0
10876         set_checksum_type $ORIG_CSUM_TYPE
10877         rm -f $DIR/$tfile
10878 }
10879 run_test 77b "checksum error on client write, read"
10880
10881 cleanup_77c() {
10882         trap 0
10883         set_checksums 0
10884         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10885         $check_ost &&
10886                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10887         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10888         $check_ost && [ -n "$ost_file_prefix" ] &&
10889                 do_facet ost1 rm -f ${ost_file_prefix}\*
10890 }
10891
10892 test_77c() {
10893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10894         $GSS && skip_env "could not run with gss"
10895         remote_ost_nodsh && skip "remote OST with nodsh"
10896
10897         local bad1
10898         local osc_file_prefix
10899         local osc_file
10900         local check_ost=false
10901         local ost_file_prefix
10902         local ost_file
10903         local orig_cksum
10904         local dump_cksum
10905         local fid
10906
10907         # ensure corruption will occur on first OSS/OST
10908         $LFS setstripe -i 0 $DIR/$tfile
10909
10910         [ ! -f $F77_TMP ] && setup_f77
10911         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10912                 error "dd write error: $?"
10913         fid=$($LFS path2fid $DIR/$tfile)
10914
10915         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10916         then
10917                 check_ost=true
10918                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10919                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10920         else
10921                 echo "OSS do not support bulk pages dump upon error"
10922         fi
10923
10924         osc_file_prefix=$($LCTL get_param -n debug_path)
10925         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10926
10927         trap cleanup_77c EXIT
10928
10929         set_checksums 1
10930         # enable bulk pages dump upon error on Client
10931         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10932         # enable bulk pages dump upon error on OSS
10933         $check_ost &&
10934                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10935
10936         # flush Client cache to allow next read to reach OSS
10937         cancel_lru_locks osc
10938
10939         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10940         $LCTL set_param fail_loc=0x80000408
10941         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10942         $LCTL set_param fail_loc=0
10943
10944         rm -f $DIR/$tfile
10945
10946         # check cksum dump on Client
10947         osc_file=$(ls ${osc_file_prefix}*)
10948         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10949         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10950         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10951         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10952         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10953                      cksum)
10954         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10955         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10956                 error "dump content does not match on Client"
10957
10958         $check_ost || skip "No need to check cksum dump on OSS"
10959
10960         # check cksum dump on OSS
10961         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10962         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10963         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10964         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10965         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10966                 error "dump content does not match on OSS"
10967
10968         cleanup_77c
10969 }
10970 run_test 77c "checksum error on client read with debug"
10971
10972 test_77d() { # bug 10889
10973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10974         $GSS && skip_env "could not run with gss"
10975
10976         stack_trap "rm -f $DIR/$tfile"
10977         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10978         $LCTL set_param fail_loc=0x80000409
10979         set_checksums 1
10980         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10981                 error "direct write: rc=$?"
10982         $LCTL set_param fail_loc=0
10983         set_checksums 0
10984
10985         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10986         $LCTL set_param fail_loc=0x80000408
10987         set_checksums 1
10988         cancel_lru_locks osc
10989         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10990                 error "direct read: rc=$?"
10991         $LCTL set_param fail_loc=0
10992         set_checksums 0
10993 }
10994 run_test 77d "checksum error on OST direct write, read"
10995
10996 test_77f() { # bug 10889
10997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10998         $GSS && skip_env "could not run with gss"
10999
11000         set_checksums 1
11001         stack_trap "rm -f $DIR/$tfile"
11002         for algo in $CKSUM_TYPES; do
11003                 cancel_lru_locks osc
11004                 set_checksum_type $algo
11005                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11006                 $LCTL set_param fail_loc=0x409
11007                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11008                         error "direct write succeeded"
11009                 $LCTL set_param fail_loc=0
11010         done
11011         set_checksum_type $ORIG_CSUM_TYPE
11012         set_checksums 0
11013 }
11014 run_test 77f "repeat checksum error on write (expect error)"
11015
11016 test_77g() { # bug 10889
11017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11018         $GSS && skip_env "could not run with gss"
11019         remote_ost_nodsh && skip "remote OST with nodsh"
11020
11021         [ ! -f $F77_TMP ] && setup_f77
11022
11023         local file=$DIR/$tfile
11024         stack_trap "rm -f $file" EXIT
11025
11026         $LFS setstripe -c 1 -i 0 $file
11027         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11028         do_facet ost1 lctl set_param fail_loc=0x8000021a
11029         set_checksums 1
11030         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11031                 error "write error: rc=$?"
11032         do_facet ost1 lctl set_param fail_loc=0
11033         set_checksums 0
11034
11035         cancel_lru_locks osc
11036         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11037         do_facet ost1 lctl set_param fail_loc=0x8000021b
11038         set_checksums 1
11039         cmp $F77_TMP $file || error "file compare failed"
11040         do_facet ost1 lctl set_param fail_loc=0
11041         set_checksums 0
11042 }
11043 run_test 77g "checksum error on OST write, read"
11044
11045 test_77k() { # LU-10906
11046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11047         $GSS && skip_env "could not run with gss"
11048
11049         local cksum_param="osc.$FSNAME*.checksums"
11050         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11051         local checksum
11052         local i
11053
11054         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11055         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11056         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11057
11058         for i in 0 1; do
11059                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11060                         error "failed to set checksum=$i on MGS"
11061                 wait_update $HOSTNAME "$get_checksum" $i
11062                 #remount
11063                 echo "remount client, checksum should be $i"
11064                 remount_client $MOUNT || error "failed to remount client"
11065                 checksum=$(eval $get_checksum)
11066                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11067         done
11068         # remove persistent param to avoid races with checksum mountopt below
11069         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11070                 error "failed to delete checksum on MGS"
11071
11072         for opt in "checksum" "nochecksum"; do
11073                 #remount with mount option
11074                 echo "remount client with option $opt, checksum should be $i"
11075                 umount_client $MOUNT || error "failed to umount client"
11076                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11077                         error "failed to mount client with option '$opt'"
11078                 checksum=$(eval $get_checksum)
11079                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11080                 i=$((i - 1))
11081         done
11082
11083         remount_client $MOUNT || error "failed to remount client"
11084 }
11085 run_test 77k "enable/disable checksum correctly"
11086
11087 test_77l() {
11088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11089         $GSS && skip_env "could not run with gss"
11090
11091         set_checksums 1
11092         stack_trap "set_checksums $ORIG_CSUM" EXIT
11093         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11094         local old
11095
11096         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11097         $LCTL set_param osc.*.idle_timeout=10
11098         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11099
11100         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11101
11102         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11103         for algo in $CKSUM_TYPES; do
11104                 set_checksum_type $algo || error "fail to set checksum type $algo"
11105                 osc_algo=$(get_osc_checksum_type OST0000)
11106                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11107
11108                 # no locks, no reqs to let the connection idle
11109                 cancel_lru_locks osc
11110                 lru_resize_disable osc
11111                 wait_osc_import_state client ost1 IDLE
11112
11113                 # ensure ost1 is connected
11114                 stat $DIR/$tfile >/dev/null || error "can't stat"
11115                 wait_osc_import_state client ost1 FULL
11116
11117                 osc_algo=$(get_osc_checksum_type OST0000)
11118                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11119         done
11120         return 0
11121 }
11122 run_test 77l "preferred checksum type is remembered after reconnected"
11123
11124 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11125 rm -f $F77_TMP
11126 unset F77_TMP
11127
11128 test_77m() {
11129         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11130                 skip "Need at least version 2.14.52"
11131         local param=checksum_speed
11132
11133         $LCTL get_param $param || error "reading $param failed"
11134
11135         csum_speeds=$($LCTL get_param -n $param)
11136
11137         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11138                 error "known checksum types are missing"
11139 }
11140 run_test 77m "Verify checksum_speed is correctly read"
11141
11142 check_filefrag_77n() {
11143         local nr_ext=0
11144         local starts=()
11145         local ends=()
11146
11147         while read extidx a b start end rest; do
11148                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11149                         nr_ext=$(( $nr_ext + 1 ))
11150                         starts+=( ${start%..} )
11151                         ends+=( ${end%:} )
11152                 fi
11153         done < <( filefrag -sv $1 )
11154
11155         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11156         return 1
11157 }
11158
11159 test_77n() {
11160         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11161
11162         touch $DIR/$tfile
11163         $TRUNCATE $DIR/$tfile 0
11164         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11165         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11166         check_filefrag_77n $DIR/$tfile ||
11167                 skip "$tfile blocks not contiguous around hole"
11168
11169         set_checksums 1
11170         stack_trap "set_checksums $ORIG_CSUM" EXIT
11171         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11172         stack_trap "rm -f $DIR/$tfile"
11173
11174         for algo in $CKSUM_TYPES; do
11175                 if [[ "$algo" =~ ^t10 ]]; then
11176                         set_checksum_type $algo ||
11177                                 error "fail to set checksum type $algo"
11178                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11179                                 error "fail to read $tfile with $algo"
11180                 fi
11181         done
11182         rm -f $DIR/$tfile
11183         return 0
11184 }
11185 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11186
11187 test_77o() {
11188         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11189                 skip "Need MDS version at least 2.14.55"
11190         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11191                 skip "Need OST version at least 2.14.55"
11192         local ofd=obdfilter
11193         local mdt=mdt
11194
11195         # print OST checksum_type
11196         echo "$ofd.$FSNAME-*.checksum_type:"
11197         do_nodes $(comma_list $(osts_nodes)) \
11198                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11199
11200         # print MDT checksum_type
11201         echo "$mdt.$FSNAME-*.checksum_type:"
11202         do_nodes $(comma_list $(mdts_nodes)) \
11203                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11204
11205         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11206                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11207
11208         (( $o_count == $OSTCOUNT )) ||
11209                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11210
11211         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11212                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11213
11214         (( $m_count == $MDSCOUNT )) ||
11215                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11216 }
11217 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11218
11219 cleanup_test_78() {
11220         trap 0
11221         rm -f $DIR/$tfile
11222 }
11223
11224 test_78() { # bug 10901
11225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11226         remote_ost || skip_env "local OST"
11227
11228         NSEQ=5
11229         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11230         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11231         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11232         echo "MemTotal: $MEMTOTAL"
11233
11234         # reserve 256MB of memory for the kernel and other running processes,
11235         # and then take 1/2 of the remaining memory for the read/write buffers.
11236         if [ $MEMTOTAL -gt 512 ] ;then
11237                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11238         else
11239                 # for those poor memory-starved high-end clusters...
11240                 MEMTOTAL=$((MEMTOTAL / 2))
11241         fi
11242         echo "Mem to use for directio: $MEMTOTAL"
11243
11244         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11245         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11246         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11247         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11248                 head -n1)
11249         echo "Smallest OST: $SMALLESTOST"
11250         [[ $SMALLESTOST -lt 10240 ]] &&
11251                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11252
11253         trap cleanup_test_78 EXIT
11254
11255         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11256                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11257
11258         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11259         echo "File size: $F78SIZE"
11260         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11261         for i in $(seq 1 $NSEQ); do
11262                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11263                 echo directIO rdwr round $i of $NSEQ
11264                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11265         done
11266
11267         cleanup_test_78
11268 }
11269 run_test 78 "handle large O_DIRECT writes correctly ============"
11270
11271 test_79() { # bug 12743
11272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11273
11274         wait_delete_completed
11275
11276         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11277         BKFREE=$(calc_osc_kbytes kbytesfree)
11278         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11279
11280         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11281         DFTOTAL=`echo $STRING | cut -d, -f1`
11282         DFUSED=`echo $STRING  | cut -d, -f2`
11283         DFAVAIL=`echo $STRING | cut -d, -f3`
11284         DFFREE=$(($DFTOTAL - $DFUSED))
11285
11286         ALLOWANCE=$((64 * $OSTCOUNT))
11287
11288         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11289            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11290                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11291         fi
11292         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11293            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11294                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11295         fi
11296         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11297            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11298                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11299         fi
11300 }
11301 run_test 79 "df report consistency check ======================="
11302
11303 test_80() { # bug 10718
11304         remote_ost_nodsh && skip "remote OST with nodsh"
11305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11306
11307         # relax strong synchronous semantics for slow backends like ZFS
11308         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11309                 local soc="obdfilter.*.sync_lock_cancel"
11310                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11311
11312                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11313                 if [ -z "$save" ]; then
11314                         soc="obdfilter.*.sync_on_lock_cancel"
11315                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11316                 fi
11317
11318                 if [ "$save" != "never" ]; then
11319                         local hosts=$(comma_list $(osts_nodes))
11320
11321                         do_nodes $hosts $LCTL set_param $soc=never
11322                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11323                 fi
11324         fi
11325
11326         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11327         sync; sleep 1; sync
11328         local before=$(date +%s)
11329         cancel_lru_locks osc
11330         local after=$(date +%s)
11331         local diff=$((after - before))
11332         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11333
11334         rm -f $DIR/$tfile
11335 }
11336 run_test 80 "Page eviction is equally fast at high offsets too"
11337
11338 test_81a() { # LU-456
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340         remote_ost_nodsh && skip "remote OST with nodsh"
11341
11342         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11343         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11344         do_facet ost1 lctl set_param fail_loc=0x80000228
11345
11346         # write should trigger a retry and success
11347         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11348         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11349         RC=$?
11350         if [ $RC -ne 0 ] ; then
11351                 error "write should success, but failed for $RC"
11352         fi
11353 }
11354 run_test 81a "OST should retry write when get -ENOSPC ==============="
11355
11356 test_81b() { # LU-456
11357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11358         remote_ost_nodsh && skip "remote OST with nodsh"
11359
11360         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11361         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11362         do_facet ost1 lctl set_param fail_loc=0x228
11363
11364         # write should retry several times and return -ENOSPC finally
11365         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11366         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11367         RC=$?
11368         ENOSPC=28
11369         if [ $RC -ne $ENOSPC ] ; then
11370                 error "dd should fail for -ENOSPC, but succeed."
11371         fi
11372 }
11373 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11374
11375 test_99() {
11376         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11377
11378         test_mkdir $DIR/$tdir.cvsroot
11379         chown $RUNAS_ID $DIR/$tdir.cvsroot
11380
11381         cd $TMP
11382         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11383
11384         cd /etc/init.d
11385         # some versions of cvs import exit(1) when asked to import links or
11386         # files they can't read.  ignore those files.
11387         local toignore=$(find . -type l -printf '-I %f\n' -o \
11388                          ! -perm /4 -printf '-I %f\n')
11389         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11390                 $tdir.reposname vtag rtag
11391
11392         cd $DIR
11393         test_mkdir $DIR/$tdir.reposname
11394         chown $RUNAS_ID $DIR/$tdir.reposname
11395         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11396
11397         cd $DIR/$tdir.reposname
11398         $RUNAS touch foo99
11399         $RUNAS cvs add -m 'addmsg' foo99
11400         $RUNAS cvs update
11401         $RUNAS cvs commit -m 'nomsg' foo99
11402         rm -fr $DIR/$tdir.cvsroot
11403 }
11404 run_test 99 "cvs strange file/directory operations"
11405
11406 test_100() {
11407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11408         [[ "$NETTYPE" =~ tcp ]] ||
11409                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11410         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11411         remote_ost_nodsh && skip "remote OST with nodsh"
11412         remote_mds_nodsh && skip "remote MDS with nodsh"
11413         remote_servers || skip "useless for local single node setup"
11414
11415         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11416                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11417
11418                 rc=0
11419                 if (( ${LOCAL/*:/} >= 1024 )); then
11420                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11421                         ss -tna
11422                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11423                 fi
11424         done
11425         (( $rc == 0 )) || error "privileged port not found" )
11426 }
11427 run_test 100 "check local port using privileged port"
11428
11429 function get_named_value()
11430 {
11431     local tag=$1
11432
11433     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11434 }
11435
11436 test_101a() {
11437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11438
11439         local s
11440         local discard
11441         local nreads=10000
11442         local cache_limit=32
11443
11444         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11445         $LCTL set_param -n llite.*.read_ahead_stats=0
11446         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11447                               awk '/^max_cached_mb/ { print $2 }')
11448         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11449         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11450
11451         #
11452         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11453         #
11454         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11455         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11456
11457         discard=0
11458         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11459                    get_named_value 'read.but.discarded'); do
11460                         discard=$(($discard + $s))
11461         done
11462
11463         $LCTL get_param osc.*-osc*.rpc_stats
11464         $LCTL get_param llite.*.read_ahead_stats
11465
11466         # Discard is generally zero, but sometimes a few random reads line up
11467         # and trigger larger readahead, which is wasted & leads to discards.
11468         if [[ $(($discard)) -gt $nreads ]]; then
11469                 error "too many ($discard) discarded pages"
11470         fi
11471         rm -f $DIR/$tfile || true
11472 }
11473 run_test 101a "check read-ahead for random reads"
11474
11475 setup_test101bc() {
11476         test_mkdir $DIR/$tdir
11477         local ssize=$1
11478         local FILE_LENGTH=$2
11479         STRIPE_OFFSET=0
11480
11481         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11482
11483         local list=$(comma_list $(osts_nodes))
11484         set_osd_param $list '' read_cache_enable 0
11485         set_osd_param $list '' writethrough_cache_enable 0
11486
11487         trap cleanup_test101bc EXIT
11488         # prepare the read-ahead file
11489         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11490
11491         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11492                                 count=$FILE_SIZE_MB 2> /dev/null
11493
11494 }
11495
11496 cleanup_test101bc() {
11497         trap 0
11498         rm -rf $DIR/$tdir
11499         rm -f $DIR/$tfile
11500
11501         local list=$(comma_list $(osts_nodes))
11502         set_osd_param $list '' read_cache_enable 1
11503         set_osd_param $list '' writethrough_cache_enable 1
11504 }
11505
11506 ra_check_101() {
11507         local read_size=$1
11508         local stripe_size=$2
11509         local stride_length=$((stripe_size / read_size))
11510         local stride_width=$((stride_length * OSTCOUNT))
11511         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11512                                 (stride_width - stride_length) ))
11513         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11514                   get_named_value 'read.but.discarded' | calc_sum)
11515
11516         if [[ $discard -gt $discard_limit ]]; then
11517                 $LCTL get_param llite.*.read_ahead_stats
11518                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11519         else
11520                 echo "Read-ahead success for size ${read_size}"
11521         fi
11522 }
11523
11524 test_101b() {
11525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11526         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11527
11528         local STRIPE_SIZE=1048576
11529         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11530
11531         if [ $SLOW == "yes" ]; then
11532                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11533         else
11534                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11535         fi
11536
11537         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11538
11539         # prepare the read-ahead file
11540         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11541         cancel_lru_locks osc
11542         for BIDX in 2 4 8 16 32 64 128 256
11543         do
11544                 local BSIZE=$((BIDX*4096))
11545                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11546                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11547                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11548                 $LCTL set_param -n llite.*.read_ahead_stats=0
11549                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11550                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11551                 cancel_lru_locks osc
11552                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11553         done
11554         cleanup_test101bc
11555         true
11556 }
11557 run_test 101b "check stride-io mode read-ahead ================="
11558
11559 test_101c() {
11560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11561
11562         local STRIPE_SIZE=1048576
11563         local FILE_LENGTH=$((STRIPE_SIZE*100))
11564         local nreads=10000
11565         local rsize=65536
11566         local osc_rpc_stats
11567
11568         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11569
11570         cancel_lru_locks osc
11571         $LCTL set_param osc.*.rpc_stats=0
11572         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11573         $LCTL get_param osc.*.rpc_stats
11574         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11575                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11576                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11577                 local size
11578
11579                 if [ $lines -le 20 ]; then
11580                         echo "continue debug"
11581                         continue
11582                 fi
11583                 for size in 1 2 4 8; do
11584                         local rpc=$(echo "$stats" |
11585                                     awk '($1 == "'$size':") {print $2; exit; }')
11586                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11587                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11588                 done
11589                 echo "$osc_rpc_stats check passed!"
11590         done
11591         cleanup_test101bc
11592         true
11593 }
11594 run_test 101c "check stripe_size aligned read-ahead"
11595
11596 test_101d() {
11597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11598
11599         local file=$DIR/$tfile
11600         local sz_MB=${FILESIZE_101d:-80}
11601         local ra_MB=${READAHEAD_MB:-40}
11602
11603         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11604         [ $free_MB -lt $sz_MB ] &&
11605                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11606
11607         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11608         $LFS setstripe -c -1 $file || error "setstripe failed"
11609
11610         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11611         echo Cancel LRU locks on lustre client to flush the client cache
11612         cancel_lru_locks osc
11613
11614         echo Disable read-ahead
11615         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11616         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11617         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11618         $LCTL get_param -n llite.*.max_read_ahead_mb
11619
11620         echo "Reading the test file $file with read-ahead disabled"
11621         local sz_KB=$((sz_MB * 1024 / 4))
11622         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11623         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11624         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11625         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11626                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11627
11628         echo "Cancel LRU locks on lustre client to flush the client cache"
11629         cancel_lru_locks osc
11630         echo Enable read-ahead with ${ra_MB}MB
11631         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11632
11633         echo "Reading the test file $file with read-ahead enabled"
11634         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11635                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11636
11637         echo "read-ahead disabled time read '$raOFF'"
11638         echo "read-ahead enabled time read '$raON'"
11639
11640         rm -f $file
11641         wait_delete_completed
11642
11643         # use awk for this check instead of bash because it handles decimals
11644         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11645                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11646 }
11647 run_test 101d "file read with and without read-ahead enabled"
11648
11649 test_101e() {
11650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11651
11652         local file=$DIR/$tfile
11653         local size_KB=500  #KB
11654         local count=100
11655         local bsize=1024
11656
11657         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11658         local need_KB=$((count * size_KB))
11659         [[ $free_KB -le $need_KB ]] &&
11660                 skip_env "Need free space $need_KB, have $free_KB"
11661
11662         echo "Creating $count ${size_KB}K test files"
11663         for ((i = 0; i < $count; i++)); do
11664                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11665         done
11666
11667         echo "Cancel LRU locks on lustre client to flush the client cache"
11668         cancel_lru_locks $OSC
11669
11670         echo "Reset readahead stats"
11671         $LCTL set_param -n llite.*.read_ahead_stats=0
11672
11673         for ((i = 0; i < $count; i++)); do
11674                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11675         done
11676
11677         $LCTL get_param llite.*.max_cached_mb
11678         $LCTL get_param llite.*.read_ahead_stats
11679         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11680                      get_named_value 'misses' | calc_sum)
11681
11682         for ((i = 0; i < $count; i++)); do
11683                 rm -rf $file.$i 2>/dev/null
11684         done
11685
11686         #10000 means 20% reads are missing in readahead
11687         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11688 }
11689 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11690
11691 test_101f() {
11692         which iozone || skip_env "no iozone installed"
11693
11694         local old_debug=$($LCTL get_param debug)
11695         old_debug=${old_debug#*=}
11696         $LCTL set_param debug="reada mmap"
11697
11698         # create a test file
11699         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11700
11701         echo Cancel LRU locks on lustre client to flush the client cache
11702         cancel_lru_locks osc
11703
11704         echo Reset readahead stats
11705         $LCTL set_param -n llite.*.read_ahead_stats=0
11706
11707         echo mmap read the file with small block size
11708         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11709                 > /dev/null 2>&1
11710
11711         echo checking missing pages
11712         $LCTL get_param llite.*.read_ahead_stats
11713         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11714                         get_named_value 'misses' | calc_sum)
11715
11716         $LCTL set_param debug="$old_debug"
11717         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11718         rm -f $DIR/$tfile
11719 }
11720 run_test 101f "check mmap read performance"
11721
11722 test_101g_brw_size_test() {
11723         local mb=$1
11724         local pages=$((mb * 1048576 / PAGE_SIZE))
11725         local file=$DIR/$tfile
11726
11727         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11728                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11729         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11730                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11731                         return 2
11732         done
11733
11734         stack_trap "rm -f $file" EXIT
11735         $LCTL set_param -n osc.*.rpc_stats=0
11736
11737         # 10 RPCs should be enough for the test
11738         local count=10
11739         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11740                 { error "dd write ${mb} MB blocks failed"; return 3; }
11741         cancel_lru_locks osc
11742         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11743                 { error "dd write ${mb} MB blocks failed"; return 4; }
11744
11745         # calculate number of full-sized read and write RPCs
11746         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11747                 sed -n '/pages per rpc/,/^$/p' |
11748                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11749                 END { print reads,writes }'))
11750         # allow one extra full-sized read RPC for async readahead
11751         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11752                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11753         [[ ${rpcs[1]} == $count ]] ||
11754                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11755 }
11756
11757 test_101g() {
11758         remote_ost_nodsh && skip "remote OST with nodsh"
11759
11760         local rpcs
11761         local osts=$(get_facets OST)
11762         local list=$(comma_list $(osts_nodes))
11763         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11764         local brw_size="obdfilter.*.brw_size"
11765
11766         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11767
11768         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11769
11770         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11771                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11772                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11773            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11774                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11775                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11776
11777                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11778                         suffix="M"
11779
11780                 if [[ $orig_mb -lt 16 ]]; then
11781                         save_lustre_params $osts "$brw_size" > $p
11782                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11783                                 error "set 16MB RPC size failed"
11784
11785                         echo "remount client to enable new RPC size"
11786                         remount_client $MOUNT || error "remount_client failed"
11787                 fi
11788
11789                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11790                 # should be able to set brw_size=12, but no rpc_stats for that
11791                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11792         fi
11793
11794         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11795
11796         if [[ $orig_mb -lt 16 ]]; then
11797                 restore_lustre_params < $p
11798                 remount_client $MOUNT || error "remount_client restore failed"
11799         fi
11800
11801         rm -f $p $DIR/$tfile
11802 }
11803 run_test 101g "Big bulk(4/16 MiB) readahead"
11804
11805 test_101h() {
11806         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11807
11808         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11809                 error "dd 70M file failed"
11810         echo Cancel LRU locks on lustre client to flush the client cache
11811         cancel_lru_locks osc
11812
11813         echo "Reset readahead stats"
11814         $LCTL set_param -n llite.*.read_ahead_stats 0
11815
11816         echo "Read 10M of data but cross 64M bundary"
11817         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11818         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11819                      get_named_value 'misses' | calc_sum)
11820         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11821         rm -f $p $DIR/$tfile
11822 }
11823 run_test 101h "Readahead should cover current read window"
11824
11825 test_101i() {
11826         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11827                 error "dd 10M file failed"
11828
11829         local max_per_file_mb=$($LCTL get_param -n \
11830                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11831         cancel_lru_locks osc
11832         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11833         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11834                 error "set max_read_ahead_per_file_mb to 1 failed"
11835
11836         echo "Reset readahead stats"
11837         $LCTL set_param llite.*.read_ahead_stats=0
11838
11839         dd if=$DIR/$tfile of=/dev/null bs=2M
11840
11841         $LCTL get_param llite.*.read_ahead_stats
11842         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11843                      awk '/misses/ { print $2 }')
11844         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11845         rm -f $DIR/$tfile
11846 }
11847 run_test 101i "allow current readahead to exceed reservation"
11848
11849 test_101j() {
11850         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11851                 error "setstripe $DIR/$tfile failed"
11852         local file_size=$((1048576 * 16))
11853         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11854         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11855
11856         echo Disable read-ahead
11857         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11858
11859         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11860         for blk in $PAGE_SIZE 1048576 $file_size; do
11861                 cancel_lru_locks osc
11862                 echo "Reset readahead stats"
11863                 $LCTL set_param -n llite.*.read_ahead_stats=0
11864                 local count=$(($file_size / $blk))
11865                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11866                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11867                              get_named_value 'failed.to.fast.read' | calc_sum)
11868                 $LCTL get_param -n llite.*.read_ahead_stats
11869                 [ $miss -eq $count ] || error "expected $count got $miss"
11870         done
11871
11872         rm -f $p $DIR/$tfile
11873 }
11874 run_test 101j "A complete read block should be submitted when no RA"
11875
11876 test_readahead_base() {
11877         local file=$DIR/$tfile
11878         local size=$1
11879         local iosz
11880         local ramax
11881         local ranum
11882
11883         $LCTL set_param -n llite.*.read_ahead_stats=0
11884         # The first page is not accounted into readahead
11885         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11886         iosz=$(((size + 1048575) / 1048576 * 1048576))
11887         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11888
11889         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11890         fallocate -l $size $file || error "failed to fallocate $file"
11891         cancel_lru_locks osc
11892         $MULTIOP $file or${iosz}c || error "failed to read $file"
11893         $LCTL get_param -n llite.*.read_ahead_stats
11894         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11895                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11896         (( $ranum <= $ramax )) ||
11897                 error "read-ahead pages is $ranum more than $ramax"
11898         rm -rf $file || error "failed to remove $file"
11899 }
11900
11901 test_101m()
11902 {
11903         local file=$DIR/$tfile
11904         local ramax
11905         local ranum
11906         local size
11907         local iosz
11908
11909         check_set_fallocate_or_skip
11910         stack_trap "rm -f $file" EXIT
11911
11912         test_readahead_base 4096
11913
11914         # file size: 16K = 16384
11915         test_readahead_base 16384
11916         test_readahead_base 16385
11917         test_readahead_base 16383
11918
11919         # file size: 1M + 1 = 1048576 + 1
11920         test_readahead_base 1048577
11921         # file size: 1M + 16K
11922         test_readahead_base $((1048576 + 16384))
11923
11924         # file size: stripe_size * (stripe_count - 1) + 16K
11925         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11926         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11927         # file size: stripe_size * stripe_count + 16K
11928         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11929         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11930         # file size: 2 * stripe_size * stripe_count + 16K
11931         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11932         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11933 }
11934 run_test 101m "read ahead for small file and last stripe of the file"
11935
11936 setup_test102() {
11937         test_mkdir $DIR/$tdir
11938         chown $RUNAS_ID $DIR/$tdir
11939         STRIPE_SIZE=65536
11940         STRIPE_OFFSET=1
11941         STRIPE_COUNT=$OSTCOUNT
11942         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11943
11944         trap cleanup_test102 EXIT
11945         cd $DIR
11946         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11947         cd $DIR/$tdir
11948         for num in 1 2 3 4; do
11949                 for count in $(seq 1 $STRIPE_COUNT); do
11950                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11951                                 local size=`expr $STRIPE_SIZE \* $num`
11952                                 local file=file"$num-$idx-$count"
11953                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11954                         done
11955                 done
11956         done
11957
11958         cd $DIR
11959         $1 tar cf $TMP/f102.tar $tdir --xattrs
11960 }
11961
11962 cleanup_test102() {
11963         trap 0
11964         rm -f $TMP/f102.tar
11965         rm -rf $DIR/d0.sanity/d102
11966 }
11967
11968 test_102a() {
11969         [ "$UID" != 0 ] && skip "must run as root"
11970         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11971                 skip_env "must have user_xattr"
11972
11973         [ -z "$(which setfattr 2>/dev/null)" ] &&
11974                 skip_env "could not find setfattr"
11975
11976         local testfile=$DIR/$tfile
11977
11978         touch $testfile
11979         echo "set/get xattr..."
11980         setfattr -n trusted.name1 -v value1 $testfile ||
11981                 error "setfattr -n trusted.name1=value1 $testfile failed"
11982         getfattr -n trusted.name1 $testfile 2> /dev/null |
11983           grep "trusted.name1=.value1" ||
11984                 error "$testfile missing trusted.name1=value1"
11985
11986         setfattr -n user.author1 -v author1 $testfile ||
11987                 error "setfattr -n user.author1=author1 $testfile failed"
11988         getfattr -n user.author1 $testfile 2> /dev/null |
11989           grep "user.author1=.author1" ||
11990                 error "$testfile missing trusted.author1=author1"
11991
11992         echo "listxattr..."
11993         setfattr -n trusted.name2 -v value2 $testfile ||
11994                 error "$testfile unable to set trusted.name2"
11995         setfattr -n trusted.name3 -v value3 $testfile ||
11996                 error "$testfile unable to set trusted.name3"
11997         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11998             grep "trusted.name" | wc -l) -eq 3 ] ||
11999                 error "$testfile missing 3 trusted.name xattrs"
12000
12001         setfattr -n user.author2 -v author2 $testfile ||
12002                 error "$testfile unable to set user.author2"
12003         setfattr -n user.author3 -v author3 $testfile ||
12004                 error "$testfile unable to set user.author3"
12005         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12006             grep "user.author" | wc -l) -eq 3 ] ||
12007                 error "$testfile missing 3 user.author xattrs"
12008
12009         echo "remove xattr..."
12010         setfattr -x trusted.name1 $testfile ||
12011                 error "$testfile error deleting trusted.name1"
12012         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12013                 error "$testfile did not delete trusted.name1 xattr"
12014
12015         setfattr -x user.author1 $testfile ||
12016                 error "$testfile error deleting user.author1"
12017         echo "set lustre special xattr ..."
12018         $LFS setstripe -c1 $testfile
12019         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12020                 awk -F "=" '/trusted.lov/ { print $2 }' )
12021         setfattr -n "trusted.lov" -v $lovea $testfile ||
12022                 error "$testfile doesn't ignore setting trusted.lov again"
12023         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12024                 error "$testfile allow setting invalid trusted.lov"
12025         rm -f $testfile
12026 }
12027 run_test 102a "user xattr test =================================="
12028
12029 check_102b_layout() {
12030         local layout="$*"
12031         local testfile=$DIR/$tfile
12032
12033         echo "test layout '$layout'"
12034         $LFS setstripe $layout $testfile || error "setstripe failed"
12035         $LFS getstripe -y $testfile
12036
12037         echo "get/set/list trusted.lov xattr ..." # b=10930
12038         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12039         [[ "$value" =~ "trusted.lov" ]] ||
12040                 error "can't get trusted.lov from $testfile"
12041         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12042                 error "getstripe failed"
12043
12044         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12045
12046         value=$(cut -d= -f2 <<<$value)
12047         # LU-13168: truncated xattr should fail if short lov_user_md header
12048         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12049                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12050         for len in $lens; do
12051                 echo "setfattr $len $testfile.2"
12052                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12053                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12054         done
12055         local stripe_size=$($LFS getstripe -S $testfile.2)
12056         local stripe_count=$($LFS getstripe -c $testfile.2)
12057         [[ $stripe_size -eq 65536 ]] ||
12058                 error "stripe size $stripe_size != 65536"
12059         [[ $stripe_count -eq $stripe_count_orig ]] ||
12060                 error "stripe count $stripe_count != $stripe_count_orig"
12061         rm $testfile $testfile.2
12062 }
12063
12064 test_102b() {
12065         [ -z "$(which setfattr 2>/dev/null)" ] &&
12066                 skip_env "could not find setfattr"
12067         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12068
12069         # check plain layout
12070         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12071
12072         # and also check composite layout
12073         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12074
12075 }
12076 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12077
12078 test_102c() {
12079         [ -z "$(which setfattr 2>/dev/null)" ] &&
12080                 skip_env "could not find setfattr"
12081         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12082
12083         # b10930: get/set/list lustre.lov xattr
12084         echo "get/set/list lustre.lov xattr ..."
12085         test_mkdir $DIR/$tdir
12086         chown $RUNAS_ID $DIR/$tdir
12087         local testfile=$DIR/$tdir/$tfile
12088         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12089                 error "setstripe failed"
12090         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12091                 error "getstripe failed"
12092         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12093         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12094
12095         local testfile2=${testfile}2
12096         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12097                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12098
12099         $RUNAS $MCREATE $testfile2
12100         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12101         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12102         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12103         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12104         [ $stripe_count -eq $STRIPECOUNT ] ||
12105                 error "stripe count $stripe_count != $STRIPECOUNT"
12106 }
12107 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12108
12109 compare_stripe_info1() {
12110         local stripe_index_all_zero=true
12111
12112         for num in 1 2 3 4; do
12113                 for count in $(seq 1 $STRIPE_COUNT); do
12114                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12115                                 local size=$((STRIPE_SIZE * num))
12116                                 local file=file"$num-$offset-$count"
12117                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12118                                 [[ $stripe_size -ne $size ]] &&
12119                                     error "$file: size $stripe_size != $size"
12120                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12121                                 # allow fewer stripes to be created, ORI-601
12122                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12123                                     error "$file: count $stripe_count != $count"
12124                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12125                                 [[ $stripe_index -ne 0 ]] &&
12126                                         stripe_index_all_zero=false
12127                         done
12128                 done
12129         done
12130         $stripe_index_all_zero &&
12131                 error "all files are being extracted starting from OST index 0"
12132         return 0
12133 }
12134
12135 have_xattrs_include() {
12136         tar --help | grep -q xattrs-include &&
12137                 echo --xattrs-include="lustre.*"
12138 }
12139
12140 test_102d() {
12141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12142         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12143
12144         XINC=$(have_xattrs_include)
12145         setup_test102
12146         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12147         cd $DIR/$tdir/$tdir
12148         compare_stripe_info1
12149 }
12150 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12151
12152 test_102f() {
12153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12154         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12155
12156         XINC=$(have_xattrs_include)
12157         setup_test102
12158         test_mkdir $DIR/$tdir.restore
12159         cd $DIR
12160         tar cf - --xattrs $tdir | tar xf - \
12161                 -C $DIR/$tdir.restore --xattrs $XINC
12162         cd $DIR/$tdir.restore/$tdir
12163         compare_stripe_info1
12164 }
12165 run_test 102f "tar copy files, not keep osts"
12166
12167 grow_xattr() {
12168         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12169                 skip "must have user_xattr"
12170         [ -z "$(which setfattr 2>/dev/null)" ] &&
12171                 skip_env "could not find setfattr"
12172         [ -z "$(which getfattr 2>/dev/null)" ] &&
12173                 skip_env "could not find getfattr"
12174
12175         local xsize=${1:-1024}  # in bytes
12176         local file=$DIR/$tfile
12177         local value="$(generate_string $xsize)"
12178         local xbig=trusted.big
12179         local toobig=$2
12180
12181         touch $file
12182         log "save $xbig on $file"
12183         if [ -z "$toobig" ]
12184         then
12185                 setfattr -n $xbig -v $value $file ||
12186                         error "saving $xbig on $file failed"
12187         else
12188                 setfattr -n $xbig -v $value $file &&
12189                         error "saving $xbig on $file succeeded"
12190                 return 0
12191         fi
12192
12193         local orig=$(get_xattr_value $xbig $file)
12194         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12195
12196         local xsml=trusted.sml
12197         log "save $xsml on $file"
12198         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12199
12200         local new=$(get_xattr_value $xbig $file)
12201         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12202
12203         log "grow $xsml on $file"
12204         setfattr -n $xsml -v "$value" $file ||
12205                 error "growing $xsml on $file failed"
12206
12207         new=$(get_xattr_value $xbig $file)
12208         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12209         log "$xbig still valid after growing $xsml"
12210
12211         rm -f $file
12212 }
12213
12214 test_102h() { # bug 15777
12215         grow_xattr 1024
12216 }
12217 run_test 102h "grow xattr from inside inode to external block"
12218
12219 test_102ha() {
12220         large_xattr_enabled || skip_env "ea_inode feature disabled"
12221
12222         echo "setting xattr of max xattr size: $(max_xattr_size)"
12223         grow_xattr $(max_xattr_size)
12224
12225         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12226         echo "This should fail:"
12227         grow_xattr $(($(max_xattr_size) + 10)) 1
12228 }
12229 run_test 102ha "grow xattr from inside inode to external inode"
12230
12231 test_102i() { # bug 17038
12232         [ -z "$(which getfattr 2>/dev/null)" ] &&
12233                 skip "could not find getfattr"
12234
12235         touch $DIR/$tfile
12236         ln -s $DIR/$tfile $DIR/${tfile}link
12237         getfattr -n trusted.lov $DIR/$tfile ||
12238                 error "lgetxattr on $DIR/$tfile failed"
12239         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12240                 grep -i "no such attr" ||
12241                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12242         rm -f $DIR/$tfile $DIR/${tfile}link
12243 }
12244 run_test 102i "lgetxattr test on symbolic link ============"
12245
12246 test_102j() {
12247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12248         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12249
12250         XINC=$(have_xattrs_include)
12251         setup_test102 "$RUNAS"
12252         chown $RUNAS_ID $DIR/$tdir
12253         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12254         cd $DIR/$tdir/$tdir
12255         compare_stripe_info1 "$RUNAS"
12256 }
12257 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12258
12259 test_102k() {
12260         [ -z "$(which setfattr 2>/dev/null)" ] &&
12261                 skip "could not find setfattr"
12262
12263         touch $DIR/$tfile
12264         # b22187 just check that does not crash for regular file.
12265         setfattr -n trusted.lov $DIR/$tfile
12266         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12267         local test_kdir=$DIR/$tdir
12268         test_mkdir $test_kdir
12269         local default_size=$($LFS getstripe -S $test_kdir)
12270         local default_count=$($LFS getstripe -c $test_kdir)
12271         local default_offset=$($LFS getstripe -i $test_kdir)
12272         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12273                 error 'dir setstripe failed'
12274         setfattr -n trusted.lov $test_kdir
12275         local stripe_size=$($LFS getstripe -S $test_kdir)
12276         local stripe_count=$($LFS getstripe -c $test_kdir)
12277         local stripe_offset=$($LFS getstripe -i $test_kdir)
12278         [ $stripe_size -eq $default_size ] ||
12279                 error "stripe size $stripe_size != $default_size"
12280         [ $stripe_count -eq $default_count ] ||
12281                 error "stripe count $stripe_count != $default_count"
12282         [ $stripe_offset -eq $default_offset ] ||
12283                 error "stripe offset $stripe_offset != $default_offset"
12284         rm -rf $DIR/$tfile $test_kdir
12285 }
12286 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12287
12288 test_102l() {
12289         [ -z "$(which getfattr 2>/dev/null)" ] &&
12290                 skip "could not find getfattr"
12291
12292         # LU-532 trusted. xattr is invisible to non-root
12293         local testfile=$DIR/$tfile
12294
12295         touch $testfile
12296
12297         echo "listxattr as user..."
12298         chown $RUNAS_ID $testfile
12299         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12300             grep -q "trusted" &&
12301                 error "$testfile trusted xattrs are user visible"
12302
12303         return 0;
12304 }
12305 run_test 102l "listxattr size test =================================="
12306
12307 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12308         local path=$DIR/$tfile
12309         touch $path
12310
12311         listxattr_size_check $path || error "listattr_size_check $path failed"
12312 }
12313 run_test 102m "Ensure listxattr fails on small bufffer ========"
12314
12315 cleanup_test102
12316
12317 getxattr() { # getxattr path name
12318         # Return the base64 encoding of the value of xattr name on path.
12319         local path=$1
12320         local name=$2
12321
12322         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12323         # file: $path
12324         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12325         #
12326         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12327
12328         getfattr --absolute-names --encoding=base64 --name=$name $path |
12329                 awk -F= -v name=$name '$1 == name {
12330                         print substr($0, index($0, "=") + 1);
12331         }'
12332 }
12333
12334 test_102n() { # LU-4101 mdt: protect internal xattrs
12335         [ -z "$(which setfattr 2>/dev/null)" ] &&
12336                 skip "could not find setfattr"
12337         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12338         then
12339                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12340         fi
12341
12342         local file0=$DIR/$tfile.0
12343         local file1=$DIR/$tfile.1
12344         local xattr0=$TMP/$tfile.0
12345         local xattr1=$TMP/$tfile.1
12346         local namelist="lov lma lmv link fid version som hsm"
12347         local name
12348         local value
12349
12350         rm -rf $file0 $file1 $xattr0 $xattr1
12351         touch $file0 $file1
12352
12353         # Get 'before' xattrs of $file1.
12354         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12355
12356         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12357                 namelist+=" lfsck_namespace"
12358         for name in $namelist; do
12359                 # Try to copy xattr from $file0 to $file1.
12360                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12361
12362                 setfattr --name=trusted.$name --value="$value" $file1 ||
12363                         error "setxattr 'trusted.$name' failed"
12364
12365                 # Try to set a garbage xattr.
12366                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12367
12368                 if [[ x$name == "xlov" ]]; then
12369                         setfattr --name=trusted.lov --value="$value" $file1 &&
12370                         error "setxattr invalid 'trusted.lov' success"
12371                 else
12372                         setfattr --name=trusted.$name --value="$value" $file1 ||
12373                                 error "setxattr invalid 'trusted.$name' failed"
12374                 fi
12375
12376                 # Try to remove the xattr from $file1. We don't care if this
12377                 # appears to succeed or fail, we just don't want there to be
12378                 # any changes or crashes.
12379                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12380         done
12381
12382         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12383         then
12384                 name="lfsck_ns"
12385                 # Try to copy xattr from $file0 to $file1.
12386                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12387
12388                 setfattr --name=trusted.$name --value="$value" $file1 ||
12389                         error "setxattr 'trusted.$name' failed"
12390
12391                 # Try to set a garbage xattr.
12392                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12393
12394                 setfattr --name=trusted.$name --value="$value" $file1 ||
12395                         error "setxattr 'trusted.$name' failed"
12396
12397                 # Try to remove the xattr from $file1. We don't care if this
12398                 # appears to succeed or fail, we just don't want there to be
12399                 # any changes or crashes.
12400                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12401         fi
12402
12403         # Get 'after' xattrs of file1.
12404         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12405
12406         if ! diff $xattr0 $xattr1; then
12407                 error "before and after xattrs of '$file1' differ"
12408         fi
12409
12410         rm -rf $file0 $file1 $xattr0 $xattr1
12411
12412         return 0
12413 }
12414 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12415
12416 test_102p() { # LU-4703 setxattr did not check ownership
12417         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12418                 skip "MDS needs to be at least 2.5.56"
12419
12420         local testfile=$DIR/$tfile
12421
12422         touch $testfile
12423
12424         echo "setfacl as user..."
12425         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12426         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12427
12428         echo "setfattr as user..."
12429         setfacl -m "u:$RUNAS_ID:---" $testfile
12430         $RUNAS setfattr -x system.posix_acl_access $testfile
12431         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12432 }
12433 run_test 102p "check setxattr(2) correctly fails without permission"
12434
12435 test_102q() {
12436         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12437                 skip "MDS needs to be at least 2.6.92"
12438
12439         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12440 }
12441 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12442
12443 test_102r() {
12444         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12445                 skip "MDS needs to be at least 2.6.93"
12446
12447         touch $DIR/$tfile || error "touch"
12448         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12449         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12450         rm $DIR/$tfile || error "rm"
12451
12452         #normal directory
12453         mkdir -p $DIR/$tdir || error "mkdir"
12454         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12455         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12456         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12457                 error "$testfile error deleting user.author1"
12458         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12459                 grep "user.$(basename $tdir)" &&
12460                 error "$tdir did not delete user.$(basename $tdir)"
12461         rmdir $DIR/$tdir || error "rmdir"
12462
12463         #striped directory
12464         test_mkdir $DIR/$tdir
12465         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12466         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12467         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12468                 error "$testfile error deleting user.author1"
12469         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12470                 grep "user.$(basename $tdir)" &&
12471                 error "$tdir did not delete user.$(basename $tdir)"
12472         rmdir $DIR/$tdir || error "rm striped dir"
12473 }
12474 run_test 102r "set EAs with empty values"
12475
12476 test_102s() {
12477         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12478                 skip "MDS needs to be at least 2.11.52"
12479
12480         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12481
12482         save_lustre_params client "llite.*.xattr_cache" > $save
12483
12484         for cache in 0 1; do
12485                 lctl set_param llite.*.xattr_cache=$cache
12486
12487                 rm -f $DIR/$tfile
12488                 touch $DIR/$tfile || error "touch"
12489                 for prefix in lustre security system trusted user; do
12490                         # Note getxattr() may fail with 'Operation not
12491                         # supported' or 'No such attribute' depending
12492                         # on prefix and cache.
12493                         getfattr -n $prefix.n102s $DIR/$tfile &&
12494                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12495                 done
12496         done
12497
12498         restore_lustre_params < $save
12499 }
12500 run_test 102s "getting nonexistent xattrs should fail"
12501
12502 test_102t() {
12503         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12504                 skip "MDS needs to be at least 2.11.52"
12505
12506         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12507
12508         save_lustre_params client "llite.*.xattr_cache" > $save
12509
12510         for cache in 0 1; do
12511                 lctl set_param llite.*.xattr_cache=$cache
12512
12513                 for buf_size in 0 256; do
12514                         rm -f $DIR/$tfile
12515                         touch $DIR/$tfile || error "touch"
12516                         setfattr -n user.multiop $DIR/$tfile
12517                         $MULTIOP $DIR/$tfile oa$buf_size ||
12518                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12519                 done
12520         done
12521
12522         restore_lustre_params < $save
12523 }
12524 run_test 102t "zero length xattr values handled correctly"
12525
12526 run_acl_subtest()
12527 {
12528         local test=$LUSTRE/tests/acl/$1.test
12529         local tmp=$(mktemp -t $1-XXXXXX).test
12530         local bin=$2
12531         local dmn=$3
12532         local grp=$4
12533         local nbd=$5
12534         export LANG=C
12535
12536
12537         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12538         local sedgroups="-e s/:users/:$grp/g"
12539         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12540
12541         sed $sedusers $sedgroups < $test > $tmp
12542         stack_trap "rm -f $tmp"
12543         [[ -s $tmp ]] || error "sed failed to create test script"
12544
12545         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12546         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12547 }
12548
12549 test_103a() {
12550         [ "$UID" != 0 ] && skip "must run as root"
12551         $GSS && skip_env "could not run under gss"
12552         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12553                 skip_env "must have acl enabled"
12554         which setfacl || skip_env "could not find setfacl"
12555         remote_mds_nodsh && skip "remote MDS with nodsh"
12556
12557         local mdts=$(comma_list $(mdts_nodes))
12558         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12559
12560         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12561         stack_trap "[[ -z \"$saved\" ]] || \
12562                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12563
12564         ACLBIN=${ACLBIN:-"bin"}
12565         ACLDMN=${ACLDMN:-"daemon"}
12566         ACLGRP=${ACLGRP:-"users"}
12567         ACLNBD=${ACLNBD:-"nobody"}
12568
12569         if ! id $ACLBIN ||
12570            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12571                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12572                 ACLBIN=$USER0
12573                 if ! id $ACLBIN ; then
12574                         cat /etc/passwd
12575                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12576                 fi
12577         fi
12578         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12579            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12580                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12581                 ACLDMN=$USER1
12582                 if ! id $ACLDMN ; then
12583                         cat /etc/passwd
12584                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12585                 fi
12586         fi
12587         if ! getent group $ACLGRP; then
12588                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12589                 ACLGRP="$TSTUSR"
12590                 if ! getent group $ACLGRP; then
12591                         echo "cannot find group '$ACLGRP', adding it"
12592                         cat /etc/group
12593                         add_group 60000 $ACLGRP
12594                 fi
12595         fi
12596
12597         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12598         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12599         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12600
12601         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12602                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12603                 ACLGRP="$TSTUSR"
12604                 if ! getent group $ACLGRP; then
12605                         echo "cannot find group '$ACLGRP', adding it"
12606                         cat /etc/group
12607                         add_group 60000 $ACLGRP
12608                 fi
12609                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12610                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12611                         cat /etc/group
12612                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12613                 fi
12614         fi
12615
12616         gpasswd -a $ACLDMN $ACLBIN ||
12617                 error "setting client group failed"             # LU-5641
12618         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12619                 error "setting MDS group failed"                # LU-5641
12620
12621         declare -a identity_old
12622
12623         for ((num = 1; num <= $MDSCOUNT; num++)); do
12624                 switch_identity $num true || identity_old[$num]=$?
12625         done
12626
12627         SAVE_UMASK=$(umask)
12628         umask 0022
12629         mkdir -p $DIR/$tdir
12630         cd $DIR/$tdir
12631
12632         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12633         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12634         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12635         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12636         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12637         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12638         if ! id -u $ACLNBD ||
12639            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12640                 ACLNBD="nfsnobody"
12641                 if ! id -u $ACLNBD; then
12642                         ACLNBD=""
12643                 fi
12644         fi
12645         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12646                 add_group $(id -u $ACLNBD) $ACLNBD
12647                 if ! getent group $ACLNBD; then
12648                         ACLNBD=""
12649                 fi
12650         fi
12651         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12652            [[ -n "$ACLNBD" ]] && which setfattr; then
12653                 run_acl_subtest permissions_xattr \
12654                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12655         elif [[ -z "$ACLNBD" ]]; then
12656                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12657         else
12658                 echo "skip 'permission_xattr' test - missing setfattr command"
12659         fi
12660         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12661
12662         # inheritance test got from HP
12663         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12664         chmod +x make-tree || error "chmod +x failed"
12665         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12666         rm -f make-tree
12667
12668         echo "LU-974 ignore umask when acl is enabled..."
12669         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12670         if [ $MDSCOUNT -ge 2 ]; then
12671                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12672         fi
12673
12674         echo "LU-2561 newly created file is same size as directory..."
12675         if [ "$mds1_FSTYPE" != "zfs" ]; then
12676                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12677         else
12678                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12679         fi
12680
12681         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12682
12683         cd $SAVE_PWD
12684         umask $SAVE_UMASK
12685
12686         for ((num = 1; num <= $MDSCOUNT; num++)); do
12687                 if [[ "${identity_old[$num]}" == 1 ]]; then
12688                         switch_identity $num false || identity_old[$num]=$?
12689                 fi
12690         done
12691 }
12692 run_test 103a "acl test"
12693
12694 test_103b() {
12695         declare -a pids
12696         local U
12697
12698         stack_trap "rm -f $DIR/$tfile.*"
12699         for U in {0..511}; do
12700                 {
12701                 local O=$(printf "%04o" $U)
12702
12703                 umask $(printf "%04o" $((511 ^ $O)))
12704                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12705                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12706
12707                 (( $S == ($O & 0666) )) ||
12708                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12709
12710                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12711                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12712                 (( $S == ($O & 0666) )) ||
12713                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12714
12715                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12716                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12717                 (( $S == ($O & 0666) )) ||
12718                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12719                 rm -f $DIR/$tfile.[smp]$0
12720                 } &
12721                 local pid=$!
12722
12723                 # limit the concurrently running threads to 64. LU-11878
12724                 local idx=$((U % 64))
12725                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12726                 pids[idx]=$pid
12727         done
12728         wait
12729 }
12730 run_test 103b "umask lfs setstripe"
12731
12732 test_103c() {
12733         mkdir -p $DIR/$tdir
12734         cp -rp $DIR/$tdir $DIR/$tdir.bak
12735
12736         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12737                 error "$DIR/$tdir shouldn't contain default ACL"
12738         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12739                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12740         true
12741 }
12742 run_test 103c "'cp -rp' won't set empty acl"
12743
12744 test_103e() {
12745         local numacl
12746         local fileacl
12747         local saved_debug=$($LCTL get_param -n debug)
12748
12749         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12750                 skip "MDS needs to be at least 2.14.52"
12751
12752         large_xattr_enabled || skip_env "ea_inode feature disabled"
12753
12754         mkdir -p $DIR/$tdir
12755         # add big LOV EA to cause reply buffer overflow earlier
12756         $LFS setstripe -C 1000 $DIR/$tdir
12757         lctl set_param mdc.*-mdc*.stats=clear
12758
12759         $LCTL set_param debug=0
12760         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12761         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12762
12763         # add a large number of default ACLs (expect 8000+ for 2.13+)
12764         for U in {2..7000}; do
12765                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12766                         error "Able to add just $U default ACLs"
12767         done
12768         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12769         echo "$numacl default ACLs created"
12770
12771         stat $DIR/$tdir || error "Cannot stat directory"
12772         # check file creation
12773         touch $DIR/$tdir/$tfile ||
12774                 error "failed to create $tfile with $numacl default ACLs"
12775         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12776         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12777         echo "$fileacl ACLs were inherited"
12778         (( $fileacl == $numacl )) ||
12779                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12780         # check that new ACLs creation adds new ACLs to inherited ACLs
12781         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12782                 error "Cannot set new ACL"
12783         numacl=$((numacl + 1))
12784         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12785         (( $fileacl == $numacl )) ||
12786                 error "failed to add new ACL: $fileacl != $numacl as expected"
12787         # adds more ACLs to a file to reach their maximum at 8000+
12788         numacl=0
12789         for U in {20000..25000}; do
12790                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12791                 numacl=$((numacl + 1))
12792         done
12793         echo "Added $numacl more ACLs to the file"
12794         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12795         echo "Total $fileacl ACLs in file"
12796         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12797         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12798         rmdir $DIR/$tdir || error "Cannot remove directory"
12799 }
12800 run_test 103e "inheritance of big amount of default ACLs"
12801
12802 test_103f() {
12803         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12804                 skip "MDS needs to be at least 2.14.51"
12805
12806         large_xattr_enabled || skip_env "ea_inode feature disabled"
12807
12808         # enable changelog to consume more internal MDD buffers
12809         changelog_register
12810
12811         mkdir -p $DIR/$tdir
12812         # add big LOV EA
12813         $LFS setstripe -C 1000 $DIR/$tdir
12814         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12815         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12816         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12817         rmdir $DIR/$tdir || error "Cannot remove directory"
12818 }
12819 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12820
12821 test_104a() {
12822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12823
12824         touch $DIR/$tfile
12825         lfs df || error "lfs df failed"
12826         lfs df -ih || error "lfs df -ih failed"
12827         lfs df -h $DIR || error "lfs df -h $DIR failed"
12828         lfs df -i $DIR || error "lfs df -i $DIR failed"
12829         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12830         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12831
12832         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12833         lctl --device %$OSC deactivate
12834         lfs df || error "lfs df with deactivated OSC failed"
12835         lctl --device %$OSC activate
12836         # wait the osc back to normal
12837         wait_osc_import_ready client ost
12838
12839         lfs df || error "lfs df with reactivated OSC failed"
12840         rm -f $DIR/$tfile
12841 }
12842 run_test 104a "lfs df [-ih] [path] test ========================="
12843
12844 test_104b() {
12845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12846         [ $RUNAS_ID -eq $UID ] &&
12847                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12848
12849         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12850                         grep "Permission denied" | wc -l)))
12851         if [ $denied_cnt -ne 0 ]; then
12852                 error "lfs check servers test failed"
12853         fi
12854 }
12855 run_test 104b "$RUNAS lfs check servers test ===================="
12856
12857 #
12858 # Verify $1 is within range of $2.
12859 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12860 # $1 is <= 2% of $2. Else Fail.
12861 #
12862 value_in_range() {
12863         # Strip all units (M, G, T)
12864         actual=$(echo $1 | tr -d A-Z)
12865         expect=$(echo $2 | tr -d A-Z)
12866
12867         expect_lo=$(($expect * 98 / 100)) # 2% below
12868         expect_hi=$(($expect * 102 / 100)) # 2% above
12869
12870         # permit 2% drift above and below
12871         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12872 }
12873
12874 test_104c() {
12875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12876         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12877
12878         local ost_param="osd-zfs.$FSNAME-OST0000."
12879         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12880         local ofacets=$(get_facets OST)
12881         local mfacets=$(get_facets MDS)
12882         local saved_ost_blocks=
12883         local saved_mdt_blocks=
12884
12885         echo "Before recordsize change"
12886         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12887         df=($(df -h | grep "$MOUNT"$))
12888
12889         # For checking.
12890         echo "lfs output : ${lfs_df[*]}"
12891         echo "df  output : ${df[*]}"
12892
12893         for facet in ${ofacets//,/ }; do
12894                 if [ -z $saved_ost_blocks ]; then
12895                         saved_ost_blocks=$(do_facet $facet \
12896                                 lctl get_param -n $ost_param.blocksize)
12897                         echo "OST Blocksize: $saved_ost_blocks"
12898                 fi
12899                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12900                 do_facet $facet zfs set recordsize=32768 $ost
12901         done
12902
12903         # BS too small. Sufficient for functional testing.
12904         for facet in ${mfacets//,/ }; do
12905                 if [ -z $saved_mdt_blocks ]; then
12906                         saved_mdt_blocks=$(do_facet $facet \
12907                                 lctl get_param -n $mdt_param.blocksize)
12908                         echo "MDT Blocksize: $saved_mdt_blocks"
12909                 fi
12910                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12911                 do_facet $facet zfs set recordsize=32768 $mdt
12912         done
12913
12914         # Give new values chance to reflect change
12915         sleep 2
12916
12917         echo "After recordsize change"
12918         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12919         df_after=($(df -h | grep "$MOUNT"$))
12920
12921         # For checking.
12922         echo "lfs output : ${lfs_df_after[*]}"
12923         echo "df  output : ${df_after[*]}"
12924
12925         # Verify lfs df
12926         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12927                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12928         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12929                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12930         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12931                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12932
12933         # Verify df
12934         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12935                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12936         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12937                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12938         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12939                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12940
12941         # Restore MDT recordize back to original
12942         for facet in ${mfacets//,/ }; do
12943                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12944                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12945         done
12946
12947         # Restore OST recordize back to original
12948         for facet in ${ofacets//,/ }; do
12949                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12950                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12951         done
12952
12953         return 0
12954 }
12955 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12956
12957 test_104d() {
12958         (( $RUNAS_ID != $UID )) ||
12959                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12960
12961         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12962                 skip "lustre version doesn't support lctl dl with non-root"
12963
12964         # debugfs only allows root users to access files, so the
12965         # previous move of the "devices" file to debugfs broke
12966         # "lctl dl" for non-root users. The LU-9680 Netlink
12967         # interface again allows non-root users to list devices.
12968         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12969                 error "lctl dl doesn't work for non root"
12970
12971         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12972         [ "$ost_count" -eq $OSTCOUNT ]  ||
12973                 error "lctl dl reports wrong number of OST devices"
12974
12975         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12976         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12977                 error "lctl dl reports wrong number of MDT devices"
12978 }
12979 run_test 104d "$RUNAS lctl dl test"
12980
12981 test_105a() {
12982         # doesn't work on 2.4 kernels
12983         touch $DIR/$tfile
12984         if $(flock_is_enabled); then
12985                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12986         else
12987                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12988         fi
12989         rm -f $DIR/$tfile
12990 }
12991 run_test 105a "flock when mounted without -o flock test ========"
12992
12993 test_105b() {
12994         touch $DIR/$tfile
12995         if $(flock_is_enabled); then
12996                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12997         else
12998                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12999         fi
13000         rm -f $DIR/$tfile
13001 }
13002 run_test 105b "fcntl when mounted without -o flock test ========"
13003
13004 test_105c() {
13005         touch $DIR/$tfile
13006         if $(flock_is_enabled); then
13007                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13008         else
13009                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13010         fi
13011         rm -f $DIR/$tfile
13012 }
13013 run_test 105c "lockf when mounted without -o flock test"
13014
13015 test_105d() { # bug 15924
13016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13017
13018         test_mkdir $DIR/$tdir
13019         flock_is_enabled || skip_env "mount w/o flock enabled"
13020         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13021         $LCTL set_param fail_loc=0x80000315
13022         flocks_test 2 $DIR/$tdir
13023 }
13024 run_test 105d "flock race (should not freeze) ========"
13025
13026 test_105e() { # bug 22660 && 22040
13027         flock_is_enabled || skip_env "mount w/o flock enabled"
13028
13029         touch $DIR/$tfile
13030         flocks_test 3 $DIR/$tfile
13031 }
13032 run_test 105e "Two conflicting flocks from same process"
13033
13034 wait_end() {
13035         echo $*
13036         while :; do
13037                 [ -f $TMP/${tfile}_sTOP ] && return
13038                 sleep 1
13039         done
13040 }
13041
13042 test_105f() {
13043         flock_is_enabled || skip_env "mount w/o flock enabled"
13044
13045         local pmax=$(ulimit -u)
13046         local i=0
13047         touch $DIR/$tfile
13048         [ $pmax -gt 20 ] && pmax=20
13049         for((i=0; i <= $pmax; i++)) {
13050                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13051         }
13052         for((i=0; i <= 10; i++)) {
13053                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13054                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13055                 [ $locks -ge $pmax ] && break
13056                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13057                 sleep 1
13058         }
13059         touch $TMP/${tfile}_sTOP
13060         wait
13061         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13062 }
13063 run_test 105f "Enqueue same range flocks"
13064
13065 test_106() { #bug 10921
13066         test_mkdir $DIR/$tdir
13067         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13068         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13069 }
13070 run_test 106 "attempt exec of dir followed by chown of that dir"
13071
13072 test_107() {
13073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13074
13075         CDIR=`pwd`
13076         local file=core
13077
13078         cd $DIR
13079         rm -f $file
13080
13081         local save_pattern=$(sysctl -n kernel.core_pattern)
13082         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13083         sysctl -w kernel.core_pattern=$file
13084         sysctl -w kernel.core_uses_pid=0
13085
13086         ulimit -c unlimited
13087         sleep 60 &
13088         SLEEPPID=$!
13089
13090         sleep 1
13091
13092         kill -s 11 $SLEEPPID
13093         wait $SLEEPPID
13094         if [ -e $file ]; then
13095                 size=`stat -c%s $file`
13096                 [ $size -eq 0 ] && error "Fail to create core file $file"
13097         else
13098                 error "Fail to create core file $file"
13099         fi
13100         rm -f $file
13101         sysctl -w kernel.core_pattern=$save_pattern
13102         sysctl -w kernel.core_uses_pid=$save_uses_pid
13103         cd $CDIR
13104 }
13105 run_test 107 "Coredump on SIG"
13106
13107 test_110() {
13108         test_mkdir $DIR/$tdir
13109         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13110         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13111                 error "mkdir with 256 char should fail, but did not"
13112         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13113                 error "create with 255 char failed"
13114         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13115                 error "create with 256 char should fail, but did not"
13116
13117         ls -l $DIR/$tdir
13118         rm -rf $DIR/$tdir
13119 }
13120 run_test 110 "filename length checking"
13121
13122 test_116a() { # was previously test_116()
13123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13124         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13125         remote_mds_nodsh && skip "remote MDS with nodsh"
13126
13127         echo -n "Free space priority "
13128         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13129                 head -n1
13130         declare -a AVAIL
13131         free_min_max
13132
13133         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13134         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13135         stack_trap simple_cleanup_common
13136
13137         # Check if we need to generate uneven OSTs
13138         test_mkdir -p $DIR/$tdir/OST${MINI}
13139         local FILL=$((MINV / 4))
13140         local DIFF=$((MAXV - MINV))
13141         local DIFF2=$((DIFF * 100 / MINV))
13142
13143         local threshold=$(do_facet $SINGLEMDS \
13144                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13145         threshold=${threshold%%%}
13146         echo -n "Check for uneven OSTs: "
13147         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13148
13149         if [[ $DIFF2 -gt $threshold ]]; then
13150                 echo "ok"
13151                 echo "Don't need to fill OST$MINI"
13152         else
13153                 # generate uneven OSTs. Write 2% over the QOS threshold value
13154                 echo "no"
13155                 DIFF=$((threshold - DIFF2 + 2))
13156                 DIFF2=$((MINV * DIFF / 100))
13157                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13158                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13159                         error "setstripe failed"
13160                 DIFF=$((DIFF2 / 2048))
13161                 i=0
13162                 while [ $i -lt $DIFF ]; do
13163                         i=$((i + 1))
13164                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13165                                 bs=2M count=1 2>/dev/null
13166                         echo -n .
13167                 done
13168                 echo .
13169                 sync
13170                 sleep_maxage
13171                 free_min_max
13172         fi
13173
13174         DIFF=$((MAXV - MINV))
13175         DIFF2=$((DIFF * 100 / MINV))
13176         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13177         if [ $DIFF2 -gt $threshold ]; then
13178                 echo "ok"
13179         else
13180                 skip "QOS imbalance criteria not met"
13181         fi
13182
13183         MINI1=$MINI
13184         MINV1=$MINV
13185         MAXI1=$MAXI
13186         MAXV1=$MAXV
13187
13188         # now fill using QOS
13189         $LFS setstripe -c 1 $DIR/$tdir
13190         FILL=$((FILL / 200))
13191         if [ $FILL -gt 600 ]; then
13192                 FILL=600
13193         fi
13194         echo "writing $FILL files to QOS-assigned OSTs"
13195         i=0
13196         while [ $i -lt $FILL ]; do
13197                 i=$((i + 1))
13198                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13199                         count=1 2>/dev/null
13200                 echo -n .
13201         done
13202         echo "wrote $i 200k files"
13203         sync
13204         sleep_maxage
13205
13206         echo "Note: free space may not be updated, so measurements might be off"
13207         free_min_max
13208         DIFF2=$((MAXV - MINV))
13209         echo "free space delta: orig $DIFF final $DIFF2"
13210         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13211         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13212         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13213         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13214         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13215         if [[ $DIFF -gt 0 ]]; then
13216                 FILL=$((DIFF2 * 100 / DIFF - 100))
13217                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13218         fi
13219
13220         # Figure out which files were written where
13221         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13222                awk '/'$MINI1': / {print $2; exit}')
13223         echo $UUID
13224         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13225         echo "$MINC files created on smaller OST $MINI1"
13226         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13227                awk '/'$MAXI1': / {print $2; exit}')
13228         echo $UUID
13229         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13230         echo "$MAXC files created on larger OST $MAXI1"
13231         if [[ $MINC -gt 0 ]]; then
13232                 FILL=$((MAXC * 100 / MINC - 100))
13233                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13234         fi
13235         [[ $MAXC -gt $MINC ]] ||
13236                 error_ignore LU-9 "stripe QOS didn't balance free space"
13237 }
13238 run_test 116a "stripe QOS: free space balance ==================="
13239
13240 test_116b() { # LU-2093
13241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13242         remote_mds_nodsh && skip "remote MDS with nodsh"
13243
13244 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13245         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13246                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13247         [ -z "$old_rr" ] && skip "no QOS"
13248         do_facet $SINGLEMDS lctl set_param \
13249                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13250         mkdir -p $DIR/$tdir
13251         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13252         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13253         do_facet $SINGLEMDS lctl set_param fail_loc=0
13254         rm -rf $DIR/$tdir
13255         do_facet $SINGLEMDS lctl set_param \
13256                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13257 }
13258 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13259
13260 test_117() # bug 10891
13261 {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263
13264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13265         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13266         lctl set_param fail_loc=0x21e
13267         > $DIR/$tfile || error "truncate failed"
13268         lctl set_param fail_loc=0
13269         echo "Truncate succeeded."
13270         rm -f $DIR/$tfile
13271 }
13272 run_test 117 "verify osd extend =========="
13273
13274 NO_SLOW_RESENDCOUNT=4
13275 export OLD_RESENDCOUNT=""
13276 set_resend_count () {
13277         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13278         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13279         lctl set_param -n $PROC_RESENDCOUNT $1
13280         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13281 }
13282
13283 # for reduce test_118* time (b=14842)
13284 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13285
13286 # Reset async IO behavior after error case
13287 reset_async() {
13288         FILE=$DIR/reset_async
13289
13290         # Ensure all OSCs are cleared
13291         $LFS setstripe -c -1 $FILE
13292         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13293         sync
13294         rm $FILE
13295 }
13296
13297 test_118a() #bug 11710
13298 {
13299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13300
13301         reset_async
13302
13303         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13304         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13305         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13306
13307         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13308                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13309                 return 1;
13310         fi
13311         rm -f $DIR/$tfile
13312 }
13313 run_test 118a "verify O_SYNC works =========="
13314
13315 test_118b()
13316 {
13317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13318         remote_ost_nodsh && skip "remote OST with nodsh"
13319
13320         reset_async
13321
13322         #define OBD_FAIL_SRV_ENOENT 0x217
13323         set_nodes_failloc "$(osts_nodes)" 0x217
13324         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13325         RC=$?
13326         set_nodes_failloc "$(osts_nodes)" 0
13327         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13328         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13329                     grep -c writeback)
13330
13331         if [[ $RC -eq 0 ]]; then
13332                 error "Must return error due to dropped pages, rc=$RC"
13333                 return 1;
13334         fi
13335
13336         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13337                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13338                 return 1;
13339         fi
13340
13341         echo "Dirty pages not leaked on ENOENT"
13342
13343         # Due to the above error the OSC will issue all RPCs syncronously
13344         # until a subsequent RPC completes successfully without error.
13345         $MULTIOP $DIR/$tfile Ow4096yc
13346         rm -f $DIR/$tfile
13347
13348         return 0
13349 }
13350 run_test 118b "Reclaim dirty pages on fatal error =========="
13351
13352 test_118c()
13353 {
13354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13355
13356         # for 118c, restore the original resend count, LU-1940
13357         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13358                                 set_resend_count $OLD_RESENDCOUNT
13359         remote_ost_nodsh && skip "remote OST with nodsh"
13360
13361         reset_async
13362
13363         #define OBD_FAIL_OST_EROFS               0x216
13364         set_nodes_failloc "$(osts_nodes)" 0x216
13365
13366         # multiop should block due to fsync until pages are written
13367         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13368         MULTIPID=$!
13369         sleep 1
13370
13371         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13372                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13373         fi
13374
13375         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13376                     grep -c writeback)
13377         if [[ $WRITEBACK -eq 0 ]]; then
13378                 error "No page in writeback, writeback=$WRITEBACK"
13379         fi
13380
13381         set_nodes_failloc "$(osts_nodes)" 0
13382         wait $MULTIPID
13383         RC=$?
13384         if [[ $RC -ne 0 ]]; then
13385                 error "Multiop fsync failed, rc=$RC"
13386         fi
13387
13388         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13389         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13390                     grep -c writeback)
13391         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13392                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13393         fi
13394
13395         rm -f $DIR/$tfile
13396         echo "Dirty pages flushed via fsync on EROFS"
13397         return 0
13398 }
13399 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13400
13401 # continue to use small resend count to reduce test_118* time (b=14842)
13402 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13403
13404 test_118d()
13405 {
13406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13407         remote_ost_nodsh && skip "remote OST with nodsh"
13408
13409         reset_async
13410
13411         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13412         set_nodes_failloc "$(osts_nodes)" 0x214
13413         # multiop should block due to fsync until pages are written
13414         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13415         MULTIPID=$!
13416         sleep 1
13417
13418         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13419                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13420         fi
13421
13422         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13423                     grep -c writeback)
13424         if [[ $WRITEBACK -eq 0 ]]; then
13425                 error "No page in writeback, writeback=$WRITEBACK"
13426         fi
13427
13428         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13429         set_nodes_failloc "$(osts_nodes)" 0
13430
13431         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13432         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13433                     grep -c writeback)
13434         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13435                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13436         fi
13437
13438         rm -f $DIR/$tfile
13439         echo "Dirty pages gaurenteed flushed via fsync"
13440         return 0
13441 }
13442 run_test 118d "Fsync validation inject a delay of the bulk =========="
13443
13444 test_118f() {
13445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13446
13447         reset_async
13448
13449         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13450         lctl set_param fail_loc=0x8000040a
13451
13452         # Should simulate EINVAL error which is fatal
13453         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13454         RC=$?
13455         if [[ $RC -eq 0 ]]; then
13456                 error "Must return error due to dropped pages, rc=$RC"
13457         fi
13458
13459         lctl set_param fail_loc=0x0
13460
13461         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13462         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13463         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13464                     grep -c writeback)
13465         if [[ $LOCKED -ne 0 ]]; then
13466                 error "Locked pages remain in cache, locked=$LOCKED"
13467         fi
13468
13469         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13470                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13471         fi
13472
13473         rm -f $DIR/$tfile
13474         echo "No pages locked after fsync"
13475
13476         reset_async
13477         return 0
13478 }
13479 run_test 118f "Simulate unrecoverable OSC side error =========="
13480
13481 test_118g() {
13482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13483
13484         reset_async
13485
13486         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13487         lctl set_param fail_loc=0x406
13488
13489         # simulate local -ENOMEM
13490         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13491         RC=$?
13492
13493         lctl set_param fail_loc=0
13494         if [[ $RC -eq 0 ]]; then
13495                 error "Must return error due to dropped pages, rc=$RC"
13496         fi
13497
13498         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13499         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13500         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13501                         grep -c writeback)
13502         if [[ $LOCKED -ne 0 ]]; then
13503                 error "Locked pages remain in cache, locked=$LOCKED"
13504         fi
13505
13506         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13507                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13508         fi
13509
13510         rm -f $DIR/$tfile
13511         echo "No pages locked after fsync"
13512
13513         reset_async
13514         return 0
13515 }
13516 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13517
13518 test_118h() {
13519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13520         remote_ost_nodsh && skip "remote OST with nodsh"
13521
13522         reset_async
13523
13524         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13525         set_nodes_failloc "$(osts_nodes)" 0x20e
13526         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13527         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13528         RC=$?
13529
13530         set_nodes_failloc "$(osts_nodes)" 0
13531         if [[ $RC -eq 0 ]]; then
13532                 error "Must return error due to dropped pages, rc=$RC"
13533         fi
13534
13535         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13536         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13537         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13538                     grep -c writeback)
13539         if [[ $LOCKED -ne 0 ]]; then
13540                 error "Locked pages remain in cache, locked=$LOCKED"
13541         fi
13542
13543         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13544                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13545         fi
13546
13547         rm -f $DIR/$tfile
13548         echo "No pages locked after fsync"
13549
13550         return 0
13551 }
13552 run_test 118h "Verify timeout in handling recoverables errors  =========="
13553
13554 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13555
13556 test_118i() {
13557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13558         remote_ost_nodsh && skip "remote OST with nodsh"
13559
13560         reset_async
13561
13562         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13563         set_nodes_failloc "$(osts_nodes)" 0x20e
13564
13565         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13566         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13567         PID=$!
13568         sleep 5
13569         set_nodes_failloc "$(osts_nodes)" 0
13570
13571         wait $PID
13572         RC=$?
13573         if [[ $RC -ne 0 ]]; then
13574                 error "got error, but should be not, rc=$RC"
13575         fi
13576
13577         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13578         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13579         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13580         if [[ $LOCKED -ne 0 ]]; then
13581                 error "Locked pages remain in cache, locked=$LOCKED"
13582         fi
13583
13584         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13585                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13586         fi
13587
13588         rm -f $DIR/$tfile
13589         echo "No pages locked after fsync"
13590
13591         return 0
13592 }
13593 run_test 118i "Fix error before timeout in recoverable error  =========="
13594
13595 [ "$SLOW" = "no" ] && set_resend_count 4
13596
13597 test_118j() {
13598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13599         remote_ost_nodsh && skip "remote OST with nodsh"
13600
13601         reset_async
13602
13603         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13604         set_nodes_failloc "$(osts_nodes)" 0x220
13605
13606         # return -EIO from OST
13607         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13608         RC=$?
13609         set_nodes_failloc "$(osts_nodes)" 0x0
13610         if [[ $RC -eq 0 ]]; then
13611                 error "Must return error due to dropped pages, rc=$RC"
13612         fi
13613
13614         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13615         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13616         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13617         if [[ $LOCKED -ne 0 ]]; then
13618                 error "Locked pages remain in cache, locked=$LOCKED"
13619         fi
13620
13621         # in recoverable error on OST we want resend and stay until it finished
13622         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13623                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13624         fi
13625
13626         rm -f $DIR/$tfile
13627         echo "No pages locked after fsync"
13628
13629         return 0
13630 }
13631 run_test 118j "Simulate unrecoverable OST side error =========="
13632
13633 test_118k()
13634 {
13635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13636         remote_ost_nodsh && skip "remote OSTs with nodsh"
13637
13638         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13639         set_nodes_failloc "$(osts_nodes)" 0x20e
13640         test_mkdir $DIR/$tdir
13641
13642         for ((i=0;i<10;i++)); do
13643                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13644                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13645                 SLEEPPID=$!
13646                 sleep 0.500s
13647                 kill $SLEEPPID
13648                 wait $SLEEPPID
13649         done
13650
13651         set_nodes_failloc "$(osts_nodes)" 0
13652         rm -rf $DIR/$tdir
13653 }
13654 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13655
13656 test_118l() # LU-646
13657 {
13658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13659
13660         test_mkdir $DIR/$tdir
13661         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13662         rm -rf $DIR/$tdir
13663 }
13664 run_test 118l "fsync dir"
13665
13666 test_118m() # LU-3066
13667 {
13668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13669
13670         test_mkdir $DIR/$tdir
13671         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13672         rm -rf $DIR/$tdir
13673 }
13674 run_test 118m "fdatasync dir ========="
13675
13676 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13677
13678 test_118n()
13679 {
13680         local begin
13681         local end
13682
13683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13684         remote_ost_nodsh && skip "remote OSTs with nodsh"
13685
13686         # Sleep to avoid a cached response.
13687         #define OBD_STATFS_CACHE_SECONDS 1
13688         sleep 2
13689
13690         # Inject a 10 second delay in the OST_STATFS handler.
13691         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13692         set_nodes_failloc "$(osts_nodes)" 0x242
13693
13694         begin=$SECONDS
13695         stat --file-system $MOUNT > /dev/null
13696         end=$SECONDS
13697
13698         set_nodes_failloc "$(osts_nodes)" 0
13699
13700         if ((end - begin > 20)); then
13701             error "statfs took $((end - begin)) seconds, expected 10"
13702         fi
13703 }
13704 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13705
13706 test_119a() # bug 11737
13707 {
13708         BSIZE=$((512 * 1024))
13709         directio write $DIR/$tfile 0 1 $BSIZE
13710         # We ask to read two blocks, which is more than a file size.
13711         # directio will indicate an error when requested and actual
13712         # sizes aren't equeal (a normal situation in this case) and
13713         # print actual read amount.
13714         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13715         if [ "$NOB" != "$BSIZE" ]; then
13716                 error "read $NOB bytes instead of $BSIZE"
13717         fi
13718         rm -f $DIR/$tfile
13719 }
13720 run_test 119a "Short directIO read must return actual read amount"
13721
13722 test_119b() # bug 11737
13723 {
13724         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13725
13726         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13727         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13728         sync
13729         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13730                 error "direct read failed"
13731         rm -f $DIR/$tfile
13732 }
13733 run_test 119b "Sparse directIO read must return actual read amount"
13734
13735 test_119c() # bug 13099
13736 {
13737         BSIZE=1048576
13738         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13739         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13740         rm -f $DIR/$tfile
13741 }
13742 run_test 119c "Testing for direct read hitting hole"
13743
13744 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13745 # Maloo test history
13746
13747 test_119e()
13748 {
13749         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13750                 skip "Need server version at least 2.15.58"
13751         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13752
13753         local stripe_size=$((1024 * 1024)) #1 MiB
13754         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13755         local file_size=$((25 * stripe_size))
13756         local bsizes
13757
13758         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13759         stack_trap "rm -f $DIR/$tfile*"
13760
13761         # Just a bit bigger than the largest size in the test set below
13762         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13763                 error "buffered i/o to create file failed"
13764
13765         # trivial test of unaligned DIO
13766         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13767                 iflag=direct oflag=direct ||
13768                 error "trivial unaligned dio failed"
13769
13770         # Test of disabling unaligned DIO support
13771         $LCTL set_param llite.*.unaligned_dio=0
13772         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13773         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13774         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13775                 iflag=direct oflag=direct &&
13776                 error "unaligned dio succeeded when disabled"
13777         $LCTL set_param llite.*.unaligned_dio=1
13778
13779         # Clean up before next part of test
13780         rm -f $DIR/$tfile.2
13781
13782         if zfs_or_rotational; then
13783                 # DIO on ZFS can take up to 2 seconds per IO
13784                 # rotational is better, but still slow.
13785                 # Limit testing on those media to larger sizes
13786                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13787                         $((stripe_size + 1024))"
13788         else
13789                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13790                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13791                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13792                         $((stripe_size - 1)) $stripe_size \
13793                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13794                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13795         fi
13796
13797         for bs in $bsizes; do
13798                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13799                 echo "Read/write with DIO at size $bs"
13800                 # Read and write with DIO from source to dest
13801                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13802                         iflag=direct oflag=direct ||
13803                         error "dio failed"
13804
13805                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13806                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13807                         error "size incorrect, file copy read/write bsize: $bs"
13808                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13809                         error "files differ, bsize $bs"
13810                 rm -f $DIR/$tfile.2
13811         done
13812 }
13813 run_test 119e "Basic tests of dio read and write at various sizes"
13814
13815 test_119f()
13816 {
13817         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13818
13819         local stripe_size=$((1024 * 1024)) #1 MiB
13820         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13821         local file_size=$((25 * stripe_size))
13822         local bsizes
13823
13824         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13825         stack_trap "rm -f $DIR/$tfile*"
13826
13827         # Just a bit bigger than the largest size in the test set below
13828         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13829                 error "buffered i/o to create file failed"
13830
13831         if zfs_or_rotational; then
13832                 # DIO on ZFS can take up to 2 seconds per IO
13833                 # rotational is better, but still slow.
13834                 # Limit testing on those media to larger sizes
13835                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13836                         $((stripe_size + 1024))"
13837         else
13838                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13839                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13840                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13841                         $((stripe_size - 1)) $stripe_size \
13842                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13843                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13844         fi
13845
13846         for bs in $bsizes; do
13847                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13848                 # Read and write with DIO from source to dest in two
13849                 # threads - should give correct copy of file
13850
13851                 echo "bs: $bs"
13852                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13853                         oflag=direct conv=notrunc &
13854                 pid_dio1=$!
13855                 # Note block size is different here for a more interesting race
13856                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13857                         iflag=direct oflag=direct conv=notrunc &
13858                 pid_dio2=$!
13859                 wait $pid_dio1
13860                 rc1=$?
13861                 wait $pid_dio2
13862                 rc2=$?
13863                 if (( rc1 != 0 )); then
13864                         error "dio copy 1 w/bsize $bs failed: $rc1"
13865                 fi
13866                 if (( rc2 != 0 )); then
13867                         error "dio copy 2 w/bsize $bs failed: $rc2"
13868                 fi
13869
13870
13871                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13872                         error "size incorrect, file copy read/write bsize: $bs"
13873                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13874                         error "files differ, bsize $bs"
13875                 rm -f $DIR/$tfile.2
13876         done
13877 }
13878 run_test 119f "dio vs dio race"
13879
13880 test_119g()
13881 {
13882         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13883
13884         local stripe_size=$((1024 * 1024)) #1 MiB
13885         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13886         local file_size=$((25 * stripe_size))
13887         local bsizes
13888
13889         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13890         stack_trap "rm -f $DIR/$tfile*"
13891
13892         # Just a bit bigger than the largest size in the test set below
13893         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13894                 error "buffered i/o to create file failed"
13895
13896         if zfs_or_rotational; then
13897                 # DIO on ZFS can take up to 2 seconds per IO
13898                 # rotational is better, but still slow.
13899                 # Limit testing on those media to larger sizes
13900                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13901                         $((stripe_size + 1024))"
13902         else
13903                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13904                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13905                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13906                         $((stripe_size - 1)) $stripe_size \
13907                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13908                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13909         fi
13910
13911         for bs in $bsizes; do
13912                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13913                 echo "bs: $bs"
13914                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13915                         oflag=direct conv=notrunc &
13916                 pid_dio1=$!
13917                 # Buffered I/O with similar but not the same block size
13918                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13919                 pid_bio2=$!
13920                 wait $pid_dio1
13921                 rc1=$?
13922                 wait $pid_bio2
13923                 rc2=$?
13924                 if (( rc1 != 0 )); then
13925                         error "dio copy 1 w/bsize $bs failed: $rc1"
13926                 fi
13927                 if (( rc2 != 0 )); then
13928                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13929                 fi
13930
13931                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13932                         error "size incorrect"
13933                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13934                         error "files differ, bsize $bs"
13935                 rm -f $DIR/$tfile.2
13936         done
13937 }
13938 run_test 119g "dio vs buffered I/O race"
13939
13940 test_119h()
13941 {
13942         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13943
13944         local stripe_size=$((1024 * 1024)) #1 MiB
13945         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13946         local file_size=$((25 * stripe_size))
13947         local bsizes
13948
13949         stack_trap "rm -f $DIR/$tfile.*"
13950
13951         if zfs_or_rotational; then
13952                 # DIO on ZFS can take up to 2 seconds per IO
13953                 # rotational is better, but still slow.
13954                 # Limit testing on those media to larger sizes
13955                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13956                         $((stripe_size + 1024))"
13957         else
13958                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13959                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13960                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13961                         $((stripe_size - 1)) $stripe_size \
13962                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13963                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13964         fi
13965
13966         for bs in $bsizes; do
13967                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13968                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13969                 echo "unaligned writes of blocksize: $bs"
13970                 # Write a file with unaligned DIO and regular DIO, and compare
13971                 # them
13972                 # with 'u', multiop randomly unaligns the io from the buffer
13973                 $MULTIOP $DIR/$tfile.1 \
13974                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13975                         error "multiop memory unaligned write failed, $bs"
13976                 $MULTIOP $DIR/$tfile.2 \
13977                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13978                         error "multiop memory aligned write failed, $bs"
13979
13980                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13981                         error "files differ, bsize $bs"
13982                 rm -f $DIR/$tfile.*
13983         done
13984
13985         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13986         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13987                 error "dd to create source file for read failed"
13988
13989         # Just a few quick tests to make sure unaligned DIO reads don't crash
13990         for bs in $bsizes; do
13991
13992                 echo "unaligned reads of blocksize: $bs"
13993                 # with 'u', multiop randomly unaligns the io from the buffer
13994                 $MULTIOP $DIR/$tfile.1 \
13995                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13996                         error "multiop memory unaligned read failed, $bs"
13997
13998         done
13999         rm -f $DIR/$tfile*
14000 }
14001 run_test 119h "basic tests of memory unaligned dio"
14002
14003 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14004 test_119i()
14005 {
14006         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14007         which aiocp || skip_env "no aiocp installed"
14008
14009         local stripe_size=$((1024 * 1024)) #1 MiB
14010         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14011         local file_size=$((25 * stripe_size))
14012         local bsizes
14013
14014         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14015         stack_trap "rm -f $DIR/$tfile.*"
14016
14017         # Just a bit bigger than the largest size in the test set below
14018         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14019                 error "buffered i/o to create file failed"
14020
14021         if zfs_or_rotational; then
14022                 # DIO on ZFS can take up to 2 seconds per IO
14023                 # rotational is better, but still slow.
14024                 # Limit testing on those media to larger sizes
14025                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14026                         $((stripe_size + 1024))"
14027         else
14028                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14029                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14030                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14031                         $((stripe_size - 1)) $stripe_size \
14032                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14033                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14034         fi
14035
14036         # Do page aligned and NOT page aligned AIO
14037         for align in 8 512 $((PAGE_SIZE)); do
14038         # Deliberately includes a few aligned sizes
14039         for bs in $bsizes; do
14040                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14041
14042                 echo "bs: $bs, align: $align, file_size $file_size"
14043                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14044                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14045                         error "unaligned aio failed, bs: $bs, align: $align"
14046
14047                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14048                         error "size incorrect"
14049                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14050                         error "files differ"
14051                 rm -f $DIR/$tfile.2
14052         done
14053         done
14054 }
14055 run_test 119i "test unaligned aio at varying sizes"
14056
14057 test_119j()
14058 {
14059         (( $LINUX_VERSION_CODE > $(version_code 4.5.0) )) ||
14060                 skip "needs kernel > 4.5.0 for ki_flags support"
14061
14062         local rpcs
14063         dd if=/dev/urandom of=$DIR/$tfile bs=8 count=1 || error "(0) dd failed"
14064         sync
14065         $LCTL set_param -n osc.*.rpc_stats=0
14066         # Read from page cache, does not generate an rpc
14067         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(1) dd failed"
14068         $LCTL get_param osc.*.rpc_stats
14069         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14070                 sed -n '/pages per rpc/,/^$/p' |
14071                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14072                 END { print reads,writes }'))
14073         [[ ${rpcs[0]} == 0 ]] ||
14074                 error "(3) ${rpcs[0]} != 0 read RPCs"
14075
14076         # Test hybrid IO read
14077         # Force next BIO as DIO
14078         # This forces an RPC to the server
14079         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14080         $LCTL set_param fail_loc=0x1429
14081         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(4) dd failed"
14082         $LCTL get_param osc.*.rpc_stats
14083         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14084                 sed -n '/pages per rpc/,/^$/p' |
14085                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14086                 END { print reads,writes }'))
14087         [[ ${rpcs[0]} == 1 ]] ||
14088                 error "(5) ${rpcs[0]} != 1 read RPCs"
14089
14090         # Test hybrid IO write
14091         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14092         $LCTL set_param fail_loc=0x1429
14093         #NB: We do not check for 0 write RPCs in the BIO case because that
14094         # would make the test racey vs cache flushing
14095         # but the DIO case is guaranteed to generate 1 write RPC
14096         dd if=/dev/zero of=$DIR/$tfile bs=8 count=1 || error "(6) dd failed"
14097         $LCTL get_param osc.*.rpc_stats
14098         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14099                 sed -n '/pages per rpc/,/^$/p' |
14100                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14101                 END { print reads,writes }'))
14102         [[ ${rpcs[1]} == 1 ]] ||
14103                 error "(7) ${rpcs[0]} != 1 read RPCs"
14104 }
14105 run_test 119j "basic tests of hybrid IO switching"
14106
14107 test_120a() {
14108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14109         remote_mds_nodsh && skip "remote MDS with nodsh"
14110         test_mkdir -i0 -c1 $DIR/$tdir
14111         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14112                 skip_env "no early lock cancel on server"
14113
14114         lru_resize_disable mdc
14115         lru_resize_disable osc
14116         cancel_lru_locks mdc
14117         # asynchronous object destroy at MDT could cause bl ast to client
14118         cancel_lru_locks osc
14119
14120         stat $DIR/$tdir > /dev/null
14121         can1=$(do_facet mds1 \
14122                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14123                awk '/ldlm_cancel/ {print $2}')
14124         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14125                awk '/ldlm_bl_callback/ {print $2}')
14126         test_mkdir -i0 -c1 $DIR/$tdir/d1
14127         can2=$(do_facet mds1 \
14128                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14129                awk '/ldlm_cancel/ {print $2}')
14130         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14131                awk '/ldlm_bl_callback/ {print $2}')
14132         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14133         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14134         lru_resize_enable mdc
14135         lru_resize_enable osc
14136 }
14137 run_test 120a "Early Lock Cancel: mkdir test"
14138
14139 test_120b() {
14140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14141         remote_mds_nodsh && skip "remote MDS with nodsh"
14142         test_mkdir $DIR/$tdir
14143         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14144                 skip_env "no early lock cancel on server"
14145
14146         lru_resize_disable mdc
14147         lru_resize_disable osc
14148         cancel_lru_locks mdc
14149         stat $DIR/$tdir > /dev/null
14150         can1=$(do_facet $SINGLEMDS \
14151                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14152                awk '/ldlm_cancel/ {print $2}')
14153         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14154                awk '/ldlm_bl_callback/ {print $2}')
14155         touch $DIR/$tdir/f1
14156         can2=$(do_facet $SINGLEMDS \
14157                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14158                awk '/ldlm_cancel/ {print $2}')
14159         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14160                awk '/ldlm_bl_callback/ {print $2}')
14161         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14162         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14163         lru_resize_enable mdc
14164         lru_resize_enable osc
14165 }
14166 run_test 120b "Early Lock Cancel: create test"
14167
14168 test_120c() {
14169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14170         remote_mds_nodsh && skip "remote MDS with nodsh"
14171         test_mkdir -i0 -c1 $DIR/$tdir
14172         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14173                 skip "no early lock cancel on server"
14174
14175         lru_resize_disable mdc
14176         lru_resize_disable osc
14177         test_mkdir -i0 -c1 $DIR/$tdir/d1
14178         test_mkdir -i0 -c1 $DIR/$tdir/d2
14179         touch $DIR/$tdir/d1/f1
14180         cancel_lru_locks mdc
14181         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14182         can1=$(do_facet mds1 \
14183                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14184                awk '/ldlm_cancel/ {print $2}')
14185         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14186                awk '/ldlm_bl_callback/ {print $2}')
14187         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14188         can2=$(do_facet mds1 \
14189                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14190                awk '/ldlm_cancel/ {print $2}')
14191         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14192                awk '/ldlm_bl_callback/ {print $2}')
14193         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14194         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14195         lru_resize_enable mdc
14196         lru_resize_enable osc
14197 }
14198 run_test 120c "Early Lock Cancel: link test"
14199
14200 test_120d() {
14201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14202         remote_mds_nodsh && skip "remote MDS with nodsh"
14203         test_mkdir -i0 -c1 $DIR/$tdir
14204         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14205                 skip_env "no early lock cancel on server"
14206
14207         lru_resize_disable mdc
14208         lru_resize_disable osc
14209         touch $DIR/$tdir
14210         cancel_lru_locks mdc
14211         stat $DIR/$tdir > /dev/null
14212         can1=$(do_facet mds1 \
14213                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14214                awk '/ldlm_cancel/ {print $2}')
14215         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14216                awk '/ldlm_bl_callback/ {print $2}')
14217         chmod a+x $DIR/$tdir
14218         can2=$(do_facet mds1 \
14219                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14220                awk '/ldlm_cancel/ {print $2}')
14221         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14222                awk '/ldlm_bl_callback/ {print $2}')
14223         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14224         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14225         lru_resize_enable mdc
14226         lru_resize_enable osc
14227 }
14228 run_test 120d "Early Lock Cancel: setattr test"
14229
14230 test_120e() {
14231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14232         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14233                 skip_env "no early lock cancel on server"
14234         remote_mds_nodsh && skip "remote MDS with nodsh"
14235
14236         local dlmtrace_set=false
14237
14238         test_mkdir -i0 -c1 $DIR/$tdir
14239         lru_resize_disable mdc
14240         lru_resize_disable osc
14241         ! $LCTL get_param debug | grep -q dlmtrace &&
14242                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14243         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14244         cancel_lru_locks mdc
14245         cancel_lru_locks osc
14246         dd if=$DIR/$tdir/f1 of=/dev/null
14247         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14248         # XXX client can not do early lock cancel of OST lock
14249         # during unlink (LU-4206), so cancel osc lock now.
14250         sleep 2
14251         cancel_lru_locks osc
14252         can1=$(do_facet mds1 \
14253                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14254                awk '/ldlm_cancel/ {print $2}')
14255         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14256                awk '/ldlm_bl_callback/ {print $2}')
14257         unlink $DIR/$tdir/f1
14258         sleep 5
14259         can2=$(do_facet mds1 \
14260                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14261                awk '/ldlm_cancel/ {print $2}')
14262         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14263                awk '/ldlm_bl_callback/ {print $2}')
14264         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14265                 $LCTL dk $TMP/cancel.debug.txt
14266         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14267                 $LCTL dk $TMP/blocking.debug.txt
14268         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14269         lru_resize_enable mdc
14270         lru_resize_enable osc
14271 }
14272 run_test 120e "Early Lock Cancel: unlink test"
14273
14274 test_120f() {
14275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14276         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14277                 skip_env "no early lock cancel on server"
14278         remote_mds_nodsh && skip "remote MDS with nodsh"
14279
14280         test_mkdir -i0 -c1 $DIR/$tdir
14281         lru_resize_disable mdc
14282         lru_resize_disable osc
14283         test_mkdir -i0 -c1 $DIR/$tdir/d1
14284         test_mkdir -i0 -c1 $DIR/$tdir/d2
14285         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14286         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14287         cancel_lru_locks mdc
14288         cancel_lru_locks osc
14289         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14290         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14291         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14292         # XXX client can not do early lock cancel of OST lock
14293         # during rename (LU-4206), so cancel osc lock now.
14294         sleep 2
14295         cancel_lru_locks osc
14296         can1=$(do_facet mds1 \
14297                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14298                awk '/ldlm_cancel/ {print $2}')
14299         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14300                awk '/ldlm_bl_callback/ {print $2}')
14301         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14302         sleep 5
14303         can2=$(do_facet mds1 \
14304                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14305                awk '/ldlm_cancel/ {print $2}')
14306         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14307                awk '/ldlm_bl_callback/ {print $2}')
14308         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14309         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14310         lru_resize_enable mdc
14311         lru_resize_enable osc
14312 }
14313 run_test 120f "Early Lock Cancel: rename test"
14314
14315 test_120g() {
14316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14317         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14318                 skip_env "no early lock cancel on server"
14319         remote_mds_nodsh && skip "remote MDS with nodsh"
14320
14321         lru_resize_disable mdc
14322         lru_resize_disable osc
14323         count=10000
14324         echo create $count files
14325         test_mkdir $DIR/$tdir
14326         cancel_lru_locks mdc
14327         cancel_lru_locks osc
14328         t0=$(date +%s)
14329
14330         can0=$(do_facet $SINGLEMDS \
14331                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14332                awk '/ldlm_cancel/ {print $2}')
14333         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14334                awk '/ldlm_bl_callback/ {print $2}')
14335         createmany -o $DIR/$tdir/f $count
14336         sync
14337         can1=$(do_facet $SINGLEMDS \
14338                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14339                awk '/ldlm_cancel/ {print $2}')
14340         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14341                awk '/ldlm_bl_callback/ {print $2}')
14342         t1=$(date +%s)
14343         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14344         echo rm $count files
14345         rm -r $DIR/$tdir
14346         sync
14347         can2=$(do_facet $SINGLEMDS \
14348                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14349                awk '/ldlm_cancel/ {print $2}')
14350         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14351                awk '/ldlm_bl_callback/ {print $2}')
14352         t2=$(date +%s)
14353         echo total: $count removes in $((t2-t1))
14354         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14355         sleep 2
14356         # wait for commitment of removal
14357         lru_resize_enable mdc
14358         lru_resize_enable osc
14359 }
14360 run_test 120g "Early Lock Cancel: performance test"
14361
14362 test_121() { #bug #10589
14363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14364
14365         rm -rf $DIR/$tfile
14366         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14367 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14368         lctl set_param fail_loc=0x310
14369         cancel_lru_locks osc > /dev/null
14370         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14371         lctl set_param fail_loc=0
14372         [[ $reads -eq $writes ]] ||
14373                 error "read $reads blocks, must be $writes blocks"
14374 }
14375 run_test 121 "read cancel race ========="
14376
14377 test_123a_base() { # was test 123, statahead(bug 11401)
14378         local lsx="$1"
14379
14380         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14381
14382         SLOWOK=0
14383         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14384                 log "testing UP system. Performance may be lower than expected."
14385                 SLOWOK=1
14386         fi
14387         running_in_vm && SLOWOK=1
14388
14389         $LCTL set_param mdc.*.batch_stats=0
14390
14391         rm -rf $DIR/$tdir
14392         test_mkdir $DIR/$tdir
14393         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14394         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14395         MULT=10
14396         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14397                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14398
14399                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14400                 lctl set_param -n llite.*.statahead_max 0
14401                 lctl get_param llite.*.statahead_max
14402                 cancel_lru_locks mdc
14403                 cancel_lru_locks osc
14404                 stime=$(date +%s)
14405                 time $lsx $DIR/$tdir | wc -l
14406                 etime=$(date +%s)
14407                 delta=$((etime - stime))
14408                 log "$lsx $i files without statahead: $delta sec"
14409                 lctl set_param llite.*.statahead_max=$max
14410
14411                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14412                          awk '/statahead.wrong:/ { print $NF }')
14413                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14414                 cancel_lru_locks mdc
14415                 cancel_lru_locks osc
14416                 stime=$(date +%s)
14417                 time $lsx $DIR/$tdir | wc -l
14418                 etime=$(date +%s)
14419                 delta_sa=$((etime - stime))
14420                 log "$lsx $i files with statahead: $delta_sa sec"
14421                 lctl get_param -n llite.*.statahead_stats
14422                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14423                          awk '/statahead.wrong:/ { print $NF }')
14424
14425                 [[ $swrong -lt $ewrong ]] &&
14426                         log "statahead was stopped, maybe too many locks held!"
14427                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14428
14429                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14430                         max=$(lctl get_param -n llite.*.statahead_max |
14431                                 head -n 1)
14432                         lctl set_param -n llite.*.statahead_max 0
14433                         lctl get_param llite.*.statahead_max
14434                         cancel_lru_locks mdc
14435                         cancel_lru_locks osc
14436                         stime=$(date +%s)
14437                         time $lsx $DIR/$tdir | wc -l
14438                         etime=$(date +%s)
14439                         delta=$((etime - stime))
14440                         log "$lsx $i files again without statahead: $delta sec"
14441                         lctl set_param llite.*.statahead_max=$max
14442                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14443                                 if [ $SLOWOK -eq 0 ]; then
14444                                         error "$lsx $i files is slower with statahead!"
14445                                 else
14446                                         log "$lsx $i files is slower with statahead!"
14447                                 fi
14448                                 break
14449                         fi
14450                 fi
14451
14452                 [ $delta -gt 20 ] && break
14453                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14454                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14455         done
14456         log "$lsx done"
14457
14458         stime=$(date +%s)
14459         rm -r $DIR/$tdir
14460         sync
14461         etime=$(date +%s)
14462         delta=$((etime - stime))
14463         log "rm -r $DIR/$tdir/: $delta seconds"
14464         log "rm done"
14465         lctl get_param -n llite.*.statahead_stats
14466         $LCTL get_param mdc.*.batch_stats
14467 }
14468
14469 test_123aa() {
14470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14471
14472         test_123a_base "ls -l"
14473 }
14474 run_test 123aa "verify statahead work"
14475
14476 test_123ab() {
14477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14478
14479         statx_supported || skip_env "Test must be statx() syscall supported"
14480
14481         test_123a_base "$STATX -l"
14482 }
14483 run_test 123ab "verify statahead work by using statx"
14484
14485 test_123ac() {
14486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14487
14488         statx_supported || skip_env "Test must be statx() syscall supported"
14489
14490         local rpcs_before
14491         local rpcs_after
14492         local agl_before
14493         local agl_after
14494
14495         cancel_lru_locks $OSC
14496         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14497         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14498                      awk '/agl.total:/ { print $NF }')
14499         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14500         test_123a_base "$STATX --cached=always -D"
14501         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14502                     awk '/agl.total:/ { print $NF }')
14503         [ $agl_before -eq $agl_after ] ||
14504                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14505         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14506         [ $rpcs_after -eq $rpcs_before ] ||
14507                 error "$STATX should not send glimpse RPCs to $OSC"
14508 }
14509 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14510
14511 test_batch_statahead() {
14512         local max=$1
14513         local batch_max=$2
14514         local num=10000
14515         local batch_rpcs
14516         local unbatch_rpcs
14517         local hit_total
14518
14519         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14520         $LCTL set_param mdc.*.batch_stats=0
14521         $LCTL set_param llite.*.statahead_max=$max
14522         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14523         # Verify that batched statahead is faster than one without statahead
14524         test_123a_base "ls -l"
14525
14526         stack_trap "rm -rf $DIR/$tdir" EXIT
14527         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14528         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14529
14530         # unbatched statahead
14531         $LCTL set_param llite.*.statahead_batch_max=0
14532         $LCTL set_param llite.*.statahead_stats=clear
14533         $LCTL set_param mdc.*.stats=clear
14534         cancel_lru_locks mdc
14535         cancel_lru_locks osc
14536         time ls -l $DIR/$tdir | wc -l
14537         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14538         wait_update_facet client "pgrep ll_sa" "" 35 ||
14539                 error "ll_sa thread is still running"
14540         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14541                     awk '/hit.total:/ { print $NF }')
14542         # hit ratio should be larger than 75% (7500).
14543         (( $hit_total > 7500 )) ||
14544                 error "unbatched statahead hit count ($hit_total) is too low"
14545
14546         # batched statahead
14547         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14548         $LCTL set_param llite.*.statahead_stats=clear
14549         $LCTL set_param mdc.*.batch_stats=clear
14550         $LCTL set_param mdc.*.stats=clear
14551         cancel_lru_locks mdc
14552         cancel_lru_locks osc
14553         time ls -l $DIR/$tdir | wc -l
14554         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14555         # wait for statahead thread to quit and update statahead stats
14556         wait_update_facet client "pgrep ll_sa" "" 35 ||
14557                 error "ll_sa thread is still running"
14558         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14559                     awk '/hit.total:/ { print $NF }')
14560         # hit ratio should be larger than 75% (7500).
14561         (( $hit_total > 7500 )) ||
14562                 error "batched statahead hit count ($hit_total) is too low"
14563
14564         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14565         (( $unbatch_rpcs > $batch_rpcs )) ||
14566                 error "batched statahead does not reduce RPC count"
14567         $LCTL get_param mdc.*.batch_stats
14568 }
14569
14570 test_123ad() {
14571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14572
14573         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14574                 skip "Need server version at least 2.15.53"
14575
14576         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14577                 skip "Server does not support batch RPC"
14578
14579         local max
14580         local batch_max
14581
14582         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14583         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14584
14585         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14586         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14587
14588         test_batch_statahead 32 32
14589         test_batch_statahead 2048 256
14590 }
14591 run_test 123ad "Verify batching statahead works correctly"
14592
14593 test_123b () { # statahead(bug 15027)
14594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14595
14596         test_mkdir $DIR/$tdir
14597         createmany -o $DIR/$tdir/$tfile-%d 1000
14598
14599         cancel_lru_locks mdc
14600         cancel_lru_locks osc
14601
14602 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14603         lctl set_param fail_loc=0x80000803
14604         ls -lR $DIR/$tdir > /dev/null
14605         log "ls done"
14606         lctl set_param fail_loc=0x0
14607         lctl get_param -n llite.*.statahead_stats
14608         rm -r $DIR/$tdir
14609         sync
14610
14611 }
14612 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14613
14614 test_123c() {
14615         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14616
14617         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14618         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14619         touch $DIR/$tdir.1/{1..3}
14620         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14621
14622         remount_client $MOUNT
14623
14624         $MULTIOP $DIR/$tdir.0 Q
14625
14626         # let statahead to complete
14627         ls -l $DIR/$tdir.0 > /dev/null
14628
14629         testid=$(echo $TESTNAME | tr '_' ' ')
14630         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14631                 error "statahead warning" || true
14632 }
14633 run_test 123c "Can not initialize inode warning on DNE statahead"
14634
14635 test_123d() {
14636         local num=100
14637         local swrong
14638         local ewrong
14639
14640         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14641         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14642                 error "setdirstripe $DIR/$tdir failed"
14643         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14644         remount_client $MOUNT
14645         $LCTL get_param llite.*.statahead_max
14646         $LCTL set_param llite.*.statahead_stats=0 ||
14647                 error "clear statahead_stats failed"
14648         swrong=$(lctl get_param -n llite.*.statahead_stats |
14649                  awk '/statahead.wrong:/ { print $NF }')
14650         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14651         # wait for statahead thread finished to update hit/miss stats.
14652         sleep 1
14653         $LCTL get_param -n llite.*.statahead_stats
14654         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14655                  awk '/statahead.wrong:/ { print $NF }')
14656         (( $swrong == $ewrong )) ||
14657                 log "statahead was stopped, maybe too many locks held!"
14658 }
14659 run_test 123d "Statahead on striped directories works correctly"
14660
14661 test_123e() {
14662         local max
14663         local batch_max
14664         local dir=$DIR/$tdir
14665
14666         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14667                 skip "Server does not support batch RPC"
14668
14669         mkdir $dir || error "mkdir $dir failed"
14670         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14671         stack_trap "rm -rf $dir"
14672
14673         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14674
14675         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14676         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14677         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14678         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14679
14680         $LCTL set_param llite.*.statahead_max=2048
14681         $LCTL set_param llite.*.statahead_batch_max=1024
14682
14683         ls -l $dir
14684         $LCTL get_param mdc.*.batch_stats
14685         $LCTL get_param llite.*.statahead_*
14686 }
14687 run_test 123e "statahead with large wide striping"
14688
14689 test_123f() {
14690         local max
14691         local batch_max
14692         local dir=$DIR/$tdir
14693
14694         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14695                 skip "Server does not support batch RPC"
14696
14697         mkdir $dir || error "mkdir $dir failed"
14698         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14699         stack_trap "rm -rf $dir"
14700
14701         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14702
14703         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14704         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14705
14706         $LCTL set_param llite.*.statahead_max=64
14707         $LCTL set_param llite.*.statahead_batch_max=64
14708
14709         ls -l $dir
14710         lctl get_param mdc.*.batch_stats
14711         lctl get_param llite.*.statahead_*
14712
14713         $LCTL set_param llite.*.statahead_max=$max
14714         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14715 }
14716 run_test 123f "Retry mechanism with large wide striping files"
14717
14718 test_123g() {
14719         local dir=$DIR/$tdir
14720         local num=1000
14721
14722         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14723                 skip "Server does not support batch RPC"
14724
14725         mkdir $dir || error "failed to mkdir $dir"
14726         createmany -o $dir/$tfile $num || error "failed creatmany files"
14727         cancel_lru_locks mdc
14728         cancel_lru_locks osc
14729
14730         $LCTL set_param llite.*.statahead_stats=clear
14731         $LCTL set_param mdc.*.batch_stats=clear
14732         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14733                 error "aheadmany $dir with $tfile failed"
14734         wait_update_facet client "pgrep ll_sa" "" 35 ||
14735                 error "ll_sa thread is still running"
14736         $LCTL get_param -n llite.*.statahead_stats
14737         $LCTL get_param -n mdc.*.batch_stats
14738
14739         local count
14740
14741         count=$($LCTL get_param -n llite.*.statahead_stats |
14742                 awk '/hit.total:/ {print $2}')
14743         echo "Hit total: $count"
14744         # Hit ratio should be >= 75%
14745         (( $count > num * 75 / 100 )) ||
14746                 error "hit total $count is be > 75% of $num"
14747 }
14748 run_test 123g "Test for stat-ahead advise"
14749
14750 test_123h_base() {
14751         local dir=$DIR/$tdir
14752         local cmd="touch $dir/$tfile.{$1}"
14753         local fcnt=$2
14754
14755         stack_trap "rm -rf $dir"
14756         mkdir -p $dir || error "failed to mkdir $dir"
14757         eval $cmd
14758
14759         cancel_lru_locks mdc
14760         $LCTL set_param llite.*.statahead_stats=clear
14761         $LCTL set_param mdc.*.batch_stats=0
14762         $LCTL set_param llite.*.statahead_max=1024
14763         $LCTL set_param llite.*.statahead_batch_max=1024
14764         lctl get_param -n llite.*.statahead_stats
14765         du -a $dir > /dev/null
14766         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14767         wait_update_facet client "pgrep ll_sa" "" 35 ||
14768                 error "ll_sa statahead thread does not quit in 35s"
14769         $LCTL get_param -n llite.*.statahead_stats
14770         $LCTL get_param -n mdc.*.batch_stats
14771
14772         local count=$($LCTL get_param -n llite.*.statahead_stats |
14773                         awk '/fname.total:/ {print $2}')
14774
14775         [ $count == 1 ] || error "File name pattern statahead not trigger"
14776         count=$($LCTL get_param -n llite.*.statahead_stats |
14777                 awk '/hit.total:/ {print $2}')
14778         # Hit ratio should be >= 75%
14779         (( $count > fcnt * 75 / 100 )) ||
14780                 error "hit total is too low: $count"
14781         rm -rf $dir || error "rm -rf $dir failed"
14782 }
14783
14784 test_123h() {
14785         local max
14786         local batch_max
14787         local enabled
14788
14789         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14790                 skip "Server does not support batch RPC"
14791
14792         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14793         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14794         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14795         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14796         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14797         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14798
14799         $LCTL set_param llite.*.enable_statahead_fname=1
14800
14801         echo "Scan a directory with number regularized fname"
14802         test_123h_base "0..10000" 10000
14803
14804         echo "Scan a directory with zeroed padding number regularized fname"
14805         test_123h_base "000000..010000" 10000
14806 }
14807 run_test 123h "Verify statahead work with the fname pattern via du"
14808
14809 test_123i_base() {
14810         local fmt=$1
14811         local iocmd=$2
14812         local dir=$DIR/$tdir
14813         local cmd="createmany -m $fmt"
14814
14815         echo "Command:"
14816         echo "- $cmd"
14817         echo "- $iocmd"
14818         stack_trap "unlinkmany $fmt"
14819         mkdir -p $dir || error "failed to mkdir $dir"
14820         eval $cmd
14821
14822         cancel_lru_locks mdc
14823         $LCTL set_param llite.*.statahead_stats=clear
14824         $LCTL set_param mdc.*.batch_stats=0
14825
14826         echo "statahead_stats (Pre):"
14827         lctl get_param -n llite.*.statahead_stats
14828         eval $iocmd || error "$iocmd failed"
14829         echo "statahead_stats (Post):"
14830         $LCTL get_param -n llite.*.statahead_stats
14831         $LCTL get_param -n mdc.*.batch_stats
14832
14833         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14834         wait_update_facet client "pgrep ll_sa" "" 35 ||
14835                 error "ll_sa statahead thread does not quit in 35s"
14836         $LCTL get_param -n llite.*.statahead_stats
14837         $LCTL get_param -n mdc.*.batch_stats
14838
14839         local count=$($LCTL get_param -n llite.*.statahead_stats |
14840                         awk '/fname.total:/ {print $2}')
14841
14842         [ $count == 1 ] || error "File name pattern statahead not trigger"
14843         count=$($LCTL get_param -n llite.*.statahead_stats |
14844                 awk '/hit.total:/ {print $2}')
14845         # Hit ratio should be >= 75%
14846         (( $count > 750 )) || error "hit total is too low: $count"
14847 }
14848
14849 test_123i() {
14850         local dir=$DIR/$tdir
14851         local cnt=1000
14852         local max
14853         local batch_max
14854         local enabled
14855         local min
14856
14857         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14858                 skip "Server does not support batch RPC"
14859
14860         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14861         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14862         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14863         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14864         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14865         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14866         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14867         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14868         $LCTL set_param llite.*.statahead_max=1024
14869         $LCTL set_param llite.*.statahead_batch_max=32
14870         $LCTL set_param llite.*.statahead_min=64
14871         $LCTL set_param llite.*.enable_statahead_fname=1
14872
14873         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14874         test_123i_base "$dir/$tfile $cnt" \
14875                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14876 }
14877 run_test 123i "Verify statahead work with the fname indexing pattern"
14878
14879 test_124a() {
14880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14881         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14882                 skip_env "no lru resize on server"
14883
14884         local NR=2000
14885
14886         test_mkdir $DIR/$tdir
14887
14888         log "create $NR files at $DIR/$tdir"
14889         createmany -o $DIR/$tdir/f $NR ||
14890                 error "failed to create $NR files in $DIR/$tdir"
14891
14892         cancel_lru_locks mdc
14893         ls -l $DIR/$tdir > /dev/null
14894
14895         local NSDIR=""
14896         local LRU_SIZE=0
14897         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14898                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14899                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14900                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14901                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14902                         log "NSDIR=$NSDIR"
14903                         log "NS=$(basename $NSDIR)"
14904                         break
14905                 fi
14906         done
14907
14908         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14909                 skip "Not enough cached locks created!"
14910         fi
14911         log "LRU=$LRU_SIZE"
14912
14913         local SLEEP=30
14914
14915         # We know that lru resize allows one client to hold $LIMIT locks
14916         # for 10h. After that locks begin to be killed by client.
14917         local MAX_HRS=10
14918         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14919         log "LIMIT=$LIMIT"
14920         if [ $LIMIT -lt $LRU_SIZE ]; then
14921                 skip "Limit is too small $LIMIT"
14922         fi
14923
14924         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14925         # killing locks. Some time was spent for creating locks. This means
14926         # that up to the moment of sleep finish we must have killed some of
14927         # them (10-100 locks). This depends on how fast ther were created.
14928         # Many of them were touched in almost the same moment and thus will
14929         # be killed in groups.
14930         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14931
14932         # Use $LRU_SIZE_B here to take into account real number of locks
14933         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14934         local LRU_SIZE_B=$LRU_SIZE
14935         log "LVF=$LVF"
14936         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14937         log "OLD_LVF=$OLD_LVF"
14938         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14939
14940         # Let's make sure that we really have some margin. Client checks
14941         # cached locks every 10 sec.
14942         SLEEP=$((SLEEP+20))
14943         log "Sleep ${SLEEP} sec"
14944         local SEC=0
14945         while ((SEC<$SLEEP)); do
14946                 echo -n "..."
14947                 sleep 5
14948                 SEC=$((SEC+5))
14949                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14950                 echo -n "$LRU_SIZE"
14951         done
14952         echo ""
14953         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14954         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14955
14956         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14957                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14958                 unlinkmany $DIR/$tdir/f $NR
14959                 return
14960         }
14961
14962         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14963         log "unlink $NR files at $DIR/$tdir"
14964         unlinkmany $DIR/$tdir/f $NR
14965 }
14966 run_test 124a "lru resize ======================================="
14967
14968 get_max_pool_limit()
14969 {
14970         local limit=$($LCTL get_param \
14971                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14972         local max=0
14973         for l in $limit; do
14974                 if [[ $l -gt $max ]]; then
14975                         max=$l
14976                 fi
14977         done
14978         echo $max
14979 }
14980
14981 test_124b() {
14982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14983         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14984                 skip_env "no lru resize on server"
14985
14986         LIMIT=$(get_max_pool_limit)
14987
14988         NR=$(($(default_lru_size)*20))
14989         if [[ $NR -gt $LIMIT ]]; then
14990                 log "Limit lock number by $LIMIT locks"
14991                 NR=$LIMIT
14992         fi
14993
14994         IFree=$(mdsrate_inodes_available)
14995         if [ $IFree -lt $NR ]; then
14996                 log "Limit lock number by $IFree inodes"
14997                 NR=$IFree
14998         fi
14999
15000         lru_resize_disable mdc
15001         test_mkdir -p $DIR/$tdir/disable_lru_resize
15002
15003         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
15004         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
15005         cancel_lru_locks mdc
15006         stime=`date +%s`
15007         PID=""
15008         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15009         PID="$PID $!"
15010         sleep 2
15011         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15012         PID="$PID $!"
15013         sleep 2
15014         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15015         PID="$PID $!"
15016         wait $PID
15017         etime=`date +%s`
15018         nolruresize_delta=$((etime-stime))
15019         log "ls -la time: $nolruresize_delta seconds"
15020         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15021         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
15022
15023         lru_resize_enable mdc
15024         test_mkdir -p $DIR/$tdir/enable_lru_resize
15025
15026         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
15027         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
15028         cancel_lru_locks mdc
15029         stime=`date +%s`
15030         PID=""
15031         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15032         PID="$PID $!"
15033         sleep 2
15034         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15035         PID="$PID $!"
15036         sleep 2
15037         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15038         PID="$PID $!"
15039         wait $PID
15040         etime=`date +%s`
15041         lruresize_delta=$((etime-stime))
15042         log "ls -la time: $lruresize_delta seconds"
15043         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15044
15045         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15046                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15047         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15048                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15049         else
15050                 log "lru resize performs the same with no lru resize"
15051         fi
15052         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15053 }
15054 run_test 124b "lru resize (performance test) ======================="
15055
15056 test_124c() {
15057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15058         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15059                 skip_env "no lru resize on server"
15060
15061         # cache ununsed locks on client
15062         local nr=100
15063         cancel_lru_locks mdc
15064         test_mkdir $DIR/$tdir
15065         createmany -o $DIR/$tdir/f $nr ||
15066                 error "failed to create $nr files in $DIR/$tdir"
15067         ls -l $DIR/$tdir > /dev/null
15068
15069         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15070         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15071         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15072         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15073         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15074
15075         # set lru_max_age to 1 sec
15076         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15077         echo "sleep $((recalc_p * 2)) seconds..."
15078         sleep $((recalc_p * 2))
15079
15080         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15081         # restore lru_max_age
15082         $LCTL set_param -n $nsdir.lru_max_age $max_age
15083         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15084         unlinkmany $DIR/$tdir/f $nr
15085 }
15086 run_test 124c "LRUR cancel very aged locks"
15087
15088 test_124d() {
15089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15090         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15091                 skip_env "no lru resize on server"
15092
15093         # cache ununsed locks on client
15094         local nr=100
15095
15096         lru_resize_disable mdc
15097         stack_trap "lru_resize_enable mdc" EXIT
15098
15099         cancel_lru_locks mdc
15100
15101         # asynchronous object destroy at MDT could cause bl ast to client
15102         test_mkdir $DIR/$tdir
15103         createmany -o $DIR/$tdir/f $nr ||
15104                 error "failed to create $nr files in $DIR/$tdir"
15105         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15106
15107         ls -l $DIR/$tdir > /dev/null
15108
15109         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15110         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15111         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15112         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15113
15114         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15115
15116         # set lru_max_age to 1 sec
15117         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15118         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15119
15120         echo "sleep $((recalc_p * 2)) seconds..."
15121         sleep $((recalc_p * 2))
15122
15123         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15124
15125         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15126 }
15127 run_test 124d "cancel very aged locks if lru-resize disabled"
15128
15129 test_125() { # 13358
15130         $LCTL get_param -n llite.*.client_type | grep -q local ||
15131                 skip "must run as local client"
15132         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15133                 skip_env "must have acl enabled"
15134         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15135         id $USER0 || skip_env "missing user $USER0"
15136
15137         test_mkdir $DIR/$tdir
15138         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15139         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15140                 error "setfacl $DIR/$tdir failed"
15141         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15142 }
15143 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15144
15145 test_126() { # bug 12829/13455
15146         $GSS && skip_env "must run as gss disabled"
15147         $LCTL get_param -n llite.*.client_type | grep -q local ||
15148                 skip "must run as local client"
15149         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15150
15151         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15152         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15153         rm -f $DIR/$tfile
15154         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15155 }
15156 run_test 126 "check that the fsgid provided by the client is taken into account"
15157
15158 test_127a() { # bug 15521
15159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15160         local name count samp unit min max sum sumsq
15161         local tmpfile=$TMP/$tfile.tmp
15162
15163         # enable stats header if it is disabled
15164         $LCTL set_param enable_stats_header=1
15165
15166         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15167         echo "stats before reset"
15168         stack_trap "rm -f $tmpfile"
15169         local now=$(date +%s)
15170
15171         $LCTL get_param osc.*.stats | tee $tmpfile
15172
15173         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15174         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15175         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15176         local uptime=$(awk '{ print $1 }' /proc/uptime)
15177
15178         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15179         (( ${snapshot_time%\.*} >= $now - 5 &&
15180            ${snapshot_time%\.*} <= $now + 5 )) ||
15181                 error "snapshot_time=$snapshot_time != now=$now"
15182         # elapsed _should_ be from mount, but at least less than uptime
15183         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15184                 error "elapsed=$elapsed > uptime=$uptime"
15185         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15186            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15187                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15188
15189         $LCTL set_param osc.*.stats=0
15190         local reset=$(date +%s)
15191         local fsize=$((2048 * 1024))
15192
15193         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15194         cancel_lru_locks osc
15195         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15196
15197         now=$(date +%s)
15198         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15199         while read name count samp unit min max sum sumsq; do
15200                 [[ "$samp" == "samples" ]] || continue
15201
15202                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15203                 [ ! $min ] && error "Missing min value for $name proc entry"
15204                 eval $name=$count || error "Wrong proc format"
15205
15206                 case $name in
15207                 read_bytes|write_bytes)
15208                         [[ "$unit" =~ "bytes" ]] ||
15209                                 error "unit is not 'bytes': $unit"
15210                         (( $min >= 4096 )) || error "min is too small: $min"
15211                         (( $min <= $fsize )) || error "min is too big: $min"
15212                         (( $max >= 4096 )) || error "max is too small: $max"
15213                         (( $max <= $fsize )) || error "max is too big: $max"
15214                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15215                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15216                                 error "sumsquare is too small: $sumsq"
15217                         (( $sumsq <= $fsize * $fsize )) ||
15218                                 error "sumsquare is too big: $sumsq"
15219                         ;;
15220                 ost_read|ost_write)
15221                         [[ "$unit" =~ "usec" ]] ||
15222                                 error "unit is not 'usec': $unit"
15223                         ;;
15224                 *)      ;;
15225                 esac
15226         done < $tmpfile
15227
15228         #check that we actually got some stats
15229         [ "$read_bytes" ] || error "Missing read_bytes stats"
15230         [ "$write_bytes" ] || error "Missing write_bytes stats"
15231         [ "$read_bytes" != 0 ] || error "no read done"
15232         [ "$write_bytes" != 0 ] || error "no write done"
15233
15234         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15235         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15236         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15237
15238         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15239         (( ${snapshot_time%\.*} >= $now - 5 &&
15240            ${snapshot_time%\.*} <= $now + 5 )) ||
15241                 error "reset snapshot_time=$snapshot_time != now=$now"
15242         # elapsed should be from time of stats reset
15243         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15244            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15245                 error "reset elapsed=$elapsed > $now - $reset"
15246         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15247            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15248                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15249 }
15250 run_test 127a "verify the client stats are sane"
15251
15252 test_127b() { # bug LU-333
15253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15254         local name count samp unit min max sum sumsq
15255
15256         echo "stats before reset"
15257         $LCTL get_param llite.*.stats
15258         $LCTL set_param llite.*.stats=0
15259
15260         # perform 2 reads and writes so MAX is different from SUM.
15261         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15262         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15263         cancel_lru_locks osc
15264         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15265         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15266
15267         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15268         stack_trap "rm -f $TMP/$tfile.tmp"
15269         while read name count samp unit min max sum sumsq; do
15270                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15271                 eval $name=$count || error "Wrong proc format"
15272
15273                 case $name in
15274                 read_bytes|write_bytes)
15275                         [[ "$unit" =~ "bytes" ]] ||
15276                                 error "unit is not 'bytes': $unit"
15277                         (( $count == 2 )) || error "count is not 2: $count"
15278                         (( $min == $PAGE_SIZE )) ||
15279                                 error "min is not $PAGE_SIZE: $min"
15280                         (( $max == $PAGE_SIZE )) ||
15281                                 error "max is not $PAGE_SIZE: $max"
15282                         (( $sum == $PAGE_SIZE * 2 )) ||
15283                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15284                         ;;
15285                 read|write)
15286                         [[ "$unit" =~ "usec" ]] ||
15287                                 error "unit is not 'usec': $unit"
15288                         ;;
15289                 *)      ;;
15290                 esac
15291         done < $TMP/$tfile.tmp
15292
15293         #check that we actually got some stats
15294         [ "$read_bytes" ] || error "Missing read_bytes stats"
15295         [ "$write_bytes" ] || error "Missing write_bytes stats"
15296         [ "$read_bytes" != 0 ] || error "no read done"
15297         [ "$write_bytes" != 0 ] || error "no write done"
15298 }
15299 run_test 127b "verify the llite client stats are sane"
15300
15301 test_127c() { # LU-12394
15302         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15303         local size
15304         local bsize
15305         local reads
15306         local writes
15307         local count
15308
15309         $LCTL set_param llite.*.extents_stats=1
15310         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15311
15312         # Use two stripes so there is enough space in default config
15313         $LFS setstripe -c 2 $DIR/$tfile
15314
15315         # Extent stats start at 0-4K and go in power of two buckets
15316         # LL_HIST_START = 12 --> 2^12 = 4K
15317         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15318         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15319         # small configs
15320         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15321                 do
15322                 # Write and read, 2x each, second time at a non-zero offset
15323                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15324                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15325                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15326                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15327                 rm -f $DIR/$tfile
15328         done
15329
15330         $LCTL get_param llite.*.extents_stats
15331
15332         count=2
15333         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15334                 do
15335                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15336                                 grep -m 1 $bsize)
15337                 reads=$(echo $bucket | awk '{print $5}')
15338                 writes=$(echo $bucket | awk '{print $9}')
15339                 [ "$reads" -eq $count ] ||
15340                         error "$reads reads in < $bsize bucket, expect $count"
15341                 [ "$writes" -eq $count ] ||
15342                         error "$writes writes in < $bsize bucket, expect $count"
15343         done
15344
15345         # Test mmap write and read
15346         $LCTL set_param llite.*.extents_stats=c
15347         size=512
15348         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15349         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15350         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15351
15352         $LCTL get_param llite.*.extents_stats
15353
15354         count=$(((size*1024) / PAGE_SIZE))
15355
15356         bsize=$((2 * PAGE_SIZE / 1024))K
15357
15358         bucket=$($LCTL get_param -n llite.*.extents_stats |
15359                         grep -m 1 $bsize)
15360         reads=$(echo $bucket | awk '{print $5}')
15361         writes=$(echo $bucket | awk '{print $9}')
15362         # mmap writes fault in the page first, creating an additonal read
15363         [ "$reads" -eq $((2 * count)) ] ||
15364                 error "$reads reads in < $bsize bucket, expect $count"
15365         [ "$writes" -eq $count ] ||
15366                 error "$writes writes in < $bsize bucket, expect $count"
15367 }
15368 run_test 127c "test llite extent stats with regular & mmap i/o"
15369
15370 test_128() { # bug 15212
15371         touch $DIR/$tfile
15372         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15373                 find $DIR/$tfile
15374                 find $DIR/$tfile
15375         EOF
15376
15377         result=$(grep error $TMP/$tfile.log)
15378         rm -f $DIR/$tfile $TMP/$tfile.log
15379         [ -z "$result" ] ||
15380                 error "consecutive find's under interactive lfs failed"
15381 }
15382 run_test 128 "interactive lfs for 2 consecutive find's"
15383
15384 set_dir_limits () {
15385         local mntdev
15386         local canondev
15387         local node
15388
15389         local ldproc=/proc/fs/ldiskfs
15390         local facets=$(get_facets MDS)
15391
15392         for facet in ${facets//,/ }; do
15393                 canondev=$(ldiskfs_canon \
15394                            *.$(convert_facet2label $facet).mntdev $facet)
15395                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15396                         ldproc=/sys/fs/ldiskfs
15397                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15398                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15399         done
15400 }
15401
15402 check_mds_dmesg() {
15403         local facets=$(get_facets MDS)
15404         for facet in ${facets//,/ }; do
15405                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15406         done
15407         return 1
15408 }
15409
15410 test_129() {
15411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15412         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15413                 skip "Need MDS version with at least 2.5.56"
15414         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15415                 skip_env "ldiskfs only test"
15416         fi
15417         remote_mds_nodsh && skip "remote MDS with nodsh"
15418
15419         local ENOSPC=28
15420         local has_warning=false
15421
15422         rm -rf $DIR/$tdir
15423         mkdir -p $DIR/$tdir
15424
15425         # block size of mds1
15426         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15427         set_dir_limits $maxsize $((maxsize * 6 / 8))
15428         stack_trap "set_dir_limits 0 0"
15429         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15430         local dirsize=$(stat -c%s "$DIR/$tdir")
15431         local nfiles=0
15432         while (( $dirsize <= $maxsize )); do
15433                 $MCREATE $DIR/$tdir/file_base_$nfiles
15434                 rc=$?
15435                 # check two errors:
15436                 # ENOSPC for ext4 max_dir_size, which has been used since
15437                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15438                 if (( rc == ENOSPC )); then
15439                         set_dir_limits 0 0
15440                         echo "rc=$rc returned as expected after $nfiles files"
15441
15442                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15443                                 error "create failed w/o dir size limit"
15444
15445                         # messages may be rate limited if test is run repeatedly
15446                         check_mds_dmesg '"is approaching max"' ||
15447                                 echo "warning message should be output"
15448                         check_mds_dmesg '"has reached max"' ||
15449                                 echo "reached message should be output"
15450
15451                         dirsize=$(stat -c%s "$DIR/$tdir")
15452
15453                         [[ $dirsize -ge $maxsize ]] && return 0
15454                         error "dirsize $dirsize < $maxsize after $nfiles files"
15455                 elif (( rc != 0 )); then
15456                         break
15457                 fi
15458                 nfiles=$((nfiles + 1))
15459                 dirsize=$(stat -c%s "$DIR/$tdir")
15460         done
15461
15462         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15463 }
15464 run_test 129 "test directory size limit ========================"
15465
15466 OLDIFS="$IFS"
15467 cleanup_130() {
15468         trap 0
15469         IFS="$OLDIFS"
15470         rm -f $DIR/$tfile
15471 }
15472
15473 test_130a() {
15474         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15475         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15476
15477         trap cleanup_130 EXIT RETURN
15478
15479         local fm_file=$DIR/$tfile
15480         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15481         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15482                 error "dd failed for $fm_file"
15483
15484         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15485         filefrag -ves $fm_file
15486         local rc=$?
15487         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15488                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15489         (( $rc == 0 )) || error "filefrag $fm_file failed"
15490
15491         filefrag_op=$(filefrag -ve -k $fm_file |
15492                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15493         local lun=$($LFS getstripe -i $fm_file)
15494
15495         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15496         IFS=$'\n'
15497         local tot_len=0
15498         for line in $filefrag_op; do
15499                 local frag_lun=$(echo $line | cut -d: -f5)
15500                 local ext_len=$(echo $line | cut -d: -f4)
15501
15502                 if (( $frag_lun != $lun )); then
15503                         error "FIEMAP on 1-stripe file($fm_file) failed"
15504                         return
15505                 fi
15506                 (( tot_len += ext_len ))
15507         done
15508
15509         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15510                 error "FIEMAP on 1-stripe file($fm_file) failed"
15511                 return
15512         fi
15513
15514         echo "FIEMAP on single striped file succeeded"
15515 }
15516 run_test 130a "FIEMAP (1-stripe file)"
15517
15518 test_130b() {
15519         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15520
15521         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15522         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15523         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15524                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15525
15526         trap cleanup_130 EXIT RETURN
15527
15528         local fm_file=$DIR/$tfile
15529         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15530                 error "setstripe on $fm_file"
15531
15532         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15533                 error "dd failed on $fm_file"
15534
15535         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15536         filefrag_op=$(filefrag -ve -k $fm_file |
15537                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15538
15539         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15540                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15541
15542         IFS=$'\n'
15543         local tot_len=0
15544         local num_luns=1
15545
15546         for line in $filefrag_op; do
15547                 local frag_lun=$(echo $line | cut -d: -f5 |
15548                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15549                 local ext_len=$(echo $line | cut -d: -f4)
15550                 if (( $frag_lun != $last_lun )); then
15551                         if (( tot_len != 1024 )); then
15552                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15553                                 return
15554                         else
15555                                 (( num_luns += 1 ))
15556                                 tot_len=0
15557                         fi
15558                 fi
15559                 (( tot_len += ext_len ))
15560                 last_lun=$frag_lun
15561         done
15562         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15563                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15564                 return
15565         fi
15566
15567         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15568 }
15569 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15570
15571 test_130c() {
15572         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15573
15574         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15575         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15576         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15577                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15578
15579         trap cleanup_130 EXIT RETURN
15580
15581         local fm_file=$DIR/$tfile
15582         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15583
15584         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15585                 error "dd failed on $fm_file"
15586
15587         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15588         filefrag_op=$(filefrag -ve -k $fm_file |
15589                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15590
15591         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15592                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15593
15594         IFS=$'\n'
15595         local tot_len=0
15596         local num_luns=1
15597         for line in $filefrag_op; do
15598                 local frag_lun=$(echo $line | cut -d: -f5 |
15599                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15600                 local ext_len=$(echo $line | cut -d: -f4)
15601                 if (( $frag_lun != $last_lun )); then
15602                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15603                         if (( logical != 512 )); then
15604                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15605                                 return
15606                         fi
15607                         if (( tot_len != 512 )); then
15608                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15609                                 return
15610                         else
15611                                 (( num_luns += 1 ))
15612                                 tot_len=0
15613                         fi
15614                 fi
15615                 (( tot_len += ext_len ))
15616                 last_lun=$frag_lun
15617         done
15618         if (( num_luns != 2 || tot_len != 512 )); then
15619                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15620                 return
15621         fi
15622
15623         echo "FIEMAP on 2-stripe file with hole succeeded"
15624 }
15625 run_test 130c "FIEMAP (2-stripe file with hole)"
15626
15627 test_130d() {
15628         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15629
15630         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15631         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15632         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15633                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15634
15635         trap cleanup_130 EXIT RETURN
15636
15637         local fm_file=$DIR/$tfile
15638         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15639                         error "setstripe on $fm_file"
15640
15641         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15642         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15643                 error "dd failed on $fm_file"
15644
15645         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15646         filefrag_op=$(filefrag -ve -k $fm_file |
15647                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15648
15649         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15650                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15651
15652         IFS=$'\n'
15653         local tot_len=0
15654         local num_luns=1
15655         for line in $filefrag_op; do
15656                 local frag_lun=$(echo $line | cut -d: -f5 |
15657                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15658                 local ext_len=$(echo $line | cut -d: -f4)
15659                 if (( $frag_lun != $last_lun )); then
15660                         if (( tot_len != 1024 )); then
15661                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15662                                 return
15663                         else
15664                                 (( num_luns += 1 ))
15665                                 local tot_len=0
15666                         fi
15667                 fi
15668                 (( tot_len += ext_len ))
15669                 last_lun=$frag_lun
15670         done
15671         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15672                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15673                 return
15674         fi
15675
15676         echo "FIEMAP on N-stripe file succeeded"
15677 }
15678 run_test 130d "FIEMAP (N-stripe file)"
15679
15680 test_130e() {
15681         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15682
15683         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15684         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15685         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15686                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15687
15688         trap cleanup_130 EXIT RETURN
15689
15690         local fm_file=$DIR/$tfile
15691         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15692         stack_trap "rm -f $fm_file"
15693
15694         local num_blks=512
15695         local expected_len=$(( (num_blks / 2) * 64 ))
15696         for ((i = 0; i < $num_blks; i++)); do
15697                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15698                         conv=notrunc > /dev/null 2>&1
15699         done
15700
15701         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15702         filefrag_op=$(filefrag -ve -k $fm_file |
15703                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15704
15705         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15706
15707         IFS=$'\n'
15708         local tot_len=0
15709         local num_luns=1
15710         for line in $filefrag_op; do
15711                 local frag_lun=$(echo $line | cut -d: -f5)
15712                 local ext_len=$(echo $line | cut -d: -f4)
15713                 if (( $frag_lun != $last_lun )); then
15714                         if (( tot_len != $expected_len )); then
15715                                 error "OST$last_lun $tot_len != $expected_len"
15716                         else
15717                                 (( num_luns += 1 ))
15718                                 tot_len=0
15719                         fi
15720                 fi
15721                 (( tot_len += ext_len ))
15722                 last_lun=$frag_lun
15723         done
15724         if (( num_luns != 2 || tot_len != $expected_len )); then
15725                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15726         fi
15727
15728         echo "FIEMAP with continuation calls succeeded"
15729 }
15730 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15731
15732 test_130f() {
15733         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15734         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15735         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15736                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15737
15738         local fm_file=$DIR/$tfile
15739         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15740                 error "multiop create with lov_delay_create on $fm_file"
15741
15742         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15743         filefrag_extents=$(filefrag -vek $fm_file |
15744                            awk '/extents? found/ { print $2 }')
15745         if (( $filefrag_extents != 0 )); then
15746                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15747         fi
15748
15749         rm -f $fm_file
15750 }
15751 run_test 130f "FIEMAP (unstriped file)"
15752
15753 test_130g() {
15754         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15755                 skip "Need MDS version with at least 2.12.53 for overstriping"
15756         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15757         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15758         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15759                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15760
15761         local file=$DIR/$tfile
15762         local nr=$((OSTCOUNT * 100))
15763
15764         $LFS setstripe -C $nr -S1M $file ||
15765                 error "failed to setstripe -C $nr $file"
15766
15767         stack_trap "rm -f $file"
15768         dd if=/dev/zero of=$file count=$nr bs=1M
15769         sync
15770         nr=$($LFS getstripe -c $file)
15771
15772         local extents=$(filefrag -v $file |
15773                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15774
15775         echo "filefrag list $extents extents in file with stripecount $nr"
15776         if (( extents < nr )); then
15777                 $LFS getstripe $file
15778                 filefrag -v $file
15779                 error "filefrag printed $extents < $nr extents"
15780         fi
15781 }
15782 run_test 130g "FIEMAP (overstripe file)"
15783
15784 # Test for writev/readv
15785 test_131a() {
15786         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15787                 error "writev test failed"
15788         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15789                 error "readv failed"
15790         rm -f $DIR/$tfile
15791 }
15792 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15793
15794 test_131b() {
15795         local fsize=$((524288 + 1048576 + 1572864))
15796         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15797                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15798                         error "append writev test failed"
15799
15800         ((fsize += 1572864 + 1048576))
15801         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15802                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15803                         error "append writev test failed"
15804         rm -f $DIR/$tfile
15805 }
15806 run_test 131b "test append writev"
15807
15808 test_131c() {
15809         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15810         error "NOT PASS"
15811 }
15812 run_test 131c "test read/write on file w/o objects"
15813
15814 test_131d() {
15815         rwv -f $DIR/$tfile -w -n 1 1572864
15816         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15817         if [ "$NOB" != 1572864 ]; then
15818                 error "Short read filed: read $NOB bytes instead of 1572864"
15819         fi
15820         rm -f $DIR/$tfile
15821 }
15822 run_test 131d "test short read"
15823
15824 test_131e() {
15825         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15826         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15827         error "read hitting hole failed"
15828         rm -f $DIR/$tfile
15829 }
15830 run_test 131e "test read hitting hole"
15831
15832 check_stats() {
15833         local facet=$1
15834         local op=$2
15835         local want=${3:-0}
15836         local res
15837
15838         # open             11 samples [usecs] 468 4793 13658 35791898
15839         case $facet in
15840         mds*) res=($(do_facet $facet \
15841                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15842                  ;;
15843         ost*) res=($(do_facet $facet \
15844                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15845                  ;;
15846         *) error "Wrong facet '$facet'" ;;
15847         esac
15848         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15849         # if $want is zero, it means any stat increment is ok.
15850         if (( $want > 0 )); then
15851                 local count=${res[1]}
15852
15853                 if (( $count != $want )); then
15854                         if [[ $facet =~ "mds" ]]; then
15855                                 do_nodes $(comma_list $(mdts_nodes)) \
15856                                         $LCTL get_param mdt.*.md_stats
15857                         else
15858                                 do_nodes $(comma_list $(osts-nodes)) \
15859                                         $LCTL get_param obdfilter.*.stats
15860                         fi
15861                         error "The $op counter on $facet is $count, not $want"
15862                 fi
15863         fi
15864 }
15865
15866 test_133a() {
15867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15868         remote_ost_nodsh && skip "remote OST with nodsh"
15869         remote_mds_nodsh && skip "remote MDS with nodsh"
15870         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15871                 skip_env "MDS doesn't support rename stats"
15872
15873         local testdir=$DIR/${tdir}/stats_testdir
15874
15875         mkdir_on_mdt0 $DIR/${tdir}
15876
15877         # clear stats.
15878         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15879         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15880
15881         # verify mdt stats first.
15882         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15883         check_stats $SINGLEMDS "mkdir" 1
15884
15885         # clear "open" from "lfs mkdir" above
15886         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15887         touch ${testdir}/${tfile} || error "touch failed"
15888         check_stats $SINGLEMDS "open" 1
15889         check_stats $SINGLEMDS "close" 1
15890         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
15891                 # open should match close
15892                 ls -lR ${testdir}
15893                 check_stats $SINGLEMDS "open" 2
15894                 check_stats $SINGLEMDS "close" 2
15895         }
15896         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15897                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15898                 check_stats $SINGLEMDS "mknod" 2
15899         }
15900         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15901         check_stats $SINGLEMDS "unlink" 1
15902         rm -f ${testdir}/${tfile} || error "file remove failed"
15903         check_stats $SINGLEMDS "unlink" 2
15904
15905         # remove working dir and check mdt stats again.
15906         rmdir ${testdir} || error "rmdir failed"
15907         check_stats $SINGLEMDS "rmdir" 1
15908
15909         local testdir1=$DIR/${tdir}/stats_testdir1
15910         mkdir_on_mdt0 ${testdir}
15911         mkdir_on_mdt0 ${testdir1}
15912         touch ${testdir1}/test1
15913         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15914         check_stats $SINGLEMDS "crossdir_rename" 1
15915
15916         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15917         check_stats $SINGLEMDS "samedir_rename" 1
15918
15919         rm -rf $DIR/${tdir}
15920 }
15921 run_test 133a "Verifying MDT stats ========================================"
15922
15923 test_133b() {
15924         local res
15925
15926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15927         remote_ost_nodsh && skip "remote OST with nodsh"
15928         remote_mds_nodsh && skip "remote MDS with nodsh"
15929
15930         local testdir=$DIR/${tdir}/stats_testdir
15931
15932         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15933         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15934         touch ${testdir}/${tfile} || error "touch failed"
15935         cancel_lru_locks mdc
15936
15937         # clear stats.
15938         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15939         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15940
15941         # extra mdt stats verification.
15942         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15943         check_stats $SINGLEMDS "setattr" 1
15944         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15945         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15946         then            # LU-1740
15947                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15948                 check_stats $SINGLEMDS "getattr" 1
15949         fi
15950         rm -rf $DIR/${tdir}
15951
15952         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15953         # so the check below is not reliable
15954         [ $MDSCOUNT -eq 1 ] || return 0
15955
15956         # Sleep to avoid a cached response.
15957         #define OBD_STATFS_CACHE_SECONDS 1
15958         sleep 2
15959         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15960         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15961         $LFS df || error "lfs failed"
15962         check_stats $SINGLEMDS "statfs" 1
15963
15964         # check aggregated statfs (LU-10018)
15965         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15966                 return 0
15967         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15968                 return 0
15969         sleep 2
15970         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15971         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15972         df $DIR
15973         check_stats $SINGLEMDS "statfs" 1
15974
15975         # We want to check that the client didn't send OST_STATFS to
15976         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15977         # extra care is needed here.
15978         if remote_mds; then
15979                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15980                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15981
15982                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15983                 [ "$res" ] && error "OST got STATFS"
15984         fi
15985
15986         return 0
15987 }
15988 run_test 133b "Verifying extra MDT stats =================================="
15989
15990 test_133c() {
15991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15992         remote_ost_nodsh && skip "remote OST with nodsh"
15993         remote_mds_nodsh && skip "remote MDS with nodsh"
15994
15995         local testdir=$DIR/$tdir/stats_testdir
15996
15997         test_mkdir -p $testdir
15998
15999         # verify obdfilter stats.
16000         $LFS setstripe -c 1 -i 0 $testdir/$tfile
16001         sync
16002         cancel_lru_locks osc
16003         wait_delete_completed
16004
16005         # clear stats.
16006         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16007         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16008
16009         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
16010                 error "dd failed"
16011         sync
16012         cancel_lru_locks osc
16013         check_stats ost1 "write" 1
16014
16015         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
16016         check_stats ost1 "read" 1
16017
16018         > $testdir/$tfile || error "truncate failed"
16019         check_stats ost1 "punch" 1
16020
16021         rm -f $testdir/$tfile || error "file remove failed"
16022         wait_delete_completed
16023         check_stats ost1 "destroy" 1
16024
16025         rm -rf $DIR/$tdir
16026 }
16027 run_test 133c "Verifying OST stats ========================================"
16028
16029 order_2() {
16030         local value=$1
16031         local orig=$value
16032         local order=1
16033
16034         while [ $value -ge 2 ]; do
16035                 order=$((order*2))
16036                 value=$((value/2))
16037         done
16038
16039         if [ $orig -gt $order ]; then
16040                 order=$((order*2))
16041         fi
16042         echo $order
16043 }
16044
16045 size_in_KMGT() {
16046     local value=$1
16047     local size=('K' 'M' 'G' 'T');
16048     local i=0
16049     local size_string=$value
16050
16051     while [ $value -ge 1024 ]; do
16052         if [ $i -gt 3 ]; then
16053             #T is the biggest unit we get here, if that is bigger,
16054             #just return XXXT
16055             size_string=${value}T
16056             break
16057         fi
16058         value=$((value >> 10))
16059         if [ $value -lt 1024 ]; then
16060             size_string=${value}${size[$i]}
16061             break
16062         fi
16063         i=$((i + 1))
16064     done
16065
16066     echo $size_string
16067 }
16068
16069 get_rename_size() {
16070         local size=$1
16071         local context=${2:-.}
16072         local sample=$(do_facet $SINGLEMDS $LCTL \
16073                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16074                 grep -A1 $context |
16075                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16076         echo $sample
16077 }
16078
16079 test_133d() {
16080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16081         remote_ost_nodsh && skip "remote OST with nodsh"
16082         remote_mds_nodsh && skip "remote MDS with nodsh"
16083         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16084                 skip_env "MDS doesn't support rename stats"
16085
16086         local testdir1=$DIR/${tdir}/stats_testdir1
16087         local testdir2=$DIR/${tdir}/stats_testdir2
16088         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16089
16090         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16091
16092         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16093         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16094
16095         createmany -o $testdir1/test 512 || error "createmany failed"
16096
16097         # check samedir rename size
16098         mv ${testdir1}/test0 ${testdir1}/test_0
16099
16100         local testdir1_size=$(ls -l $DIR/${tdir} |
16101                 awk '/stats_testdir1/ {print $5}')
16102         local testdir2_size=$(ls -l $DIR/${tdir} |
16103                 awk '/stats_testdir2/ {print $5}')
16104
16105         testdir1_size=$(order_2 $testdir1_size)
16106         testdir2_size=$(order_2 $testdir2_size)
16107
16108         testdir1_size=$(size_in_KMGT $testdir1_size)
16109         testdir2_size=$(size_in_KMGT $testdir2_size)
16110
16111         echo "source rename dir size: ${testdir1_size}"
16112         echo "target rename dir size: ${testdir2_size}"
16113
16114         local cmd="do_facet $SINGLEMDS $LCTL "
16115         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16116
16117         eval $cmd || error "$cmd failed"
16118         local samedir=$($cmd | grep 'same_dir')
16119         local same_sample=$(get_rename_size $testdir1_size)
16120         [ -z "$samedir" ] && error "samedir_rename_size count error"
16121         [[ $same_sample -eq 1 ]] ||
16122                 error "samedir_rename_size error $same_sample"
16123         echo "Check same dir rename stats success"
16124
16125         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16126
16127         # check crossdir rename size
16128         mv ${testdir1}/test_0 ${testdir2}/test_0
16129
16130         testdir1_size=$(ls -l $DIR/${tdir} |
16131                 awk '/stats_testdir1/ {print $5}')
16132         testdir2_size=$(ls -l $DIR/${tdir} |
16133                 awk '/stats_testdir2/ {print $5}')
16134
16135         testdir1_size=$(order_2 $testdir1_size)
16136         testdir2_size=$(order_2 $testdir2_size)
16137
16138         testdir1_size=$(size_in_KMGT $testdir1_size)
16139         testdir2_size=$(size_in_KMGT $testdir2_size)
16140
16141         echo "source rename dir size: ${testdir1_size}"
16142         echo "target rename dir size: ${testdir2_size}"
16143
16144         eval $cmd || error "$cmd failed"
16145         local crossdir=$($cmd | grep 'crossdir')
16146         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16147         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16148         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16149         [[ $src_sample -eq 1 ]] ||
16150                 error "crossdir_rename_size error $src_sample"
16151         [[ $tgt_sample -eq 1 ]] ||
16152                 error "crossdir_rename_size error $tgt_sample"
16153         echo "Check cross dir rename stats success"
16154         rm -rf $DIR/${tdir}
16155 }
16156 run_test 133d "Verifying rename_stats ========================================"
16157
16158 test_133e() {
16159         remote_mds_nodsh && skip "remote MDS with nodsh"
16160         remote_ost_nodsh && skip "remote OST with nodsh"
16161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16162
16163         local testdir=$DIR/${tdir}/stats_testdir
16164         local ctr f0 f1 bs=32768 count=42 sum
16165
16166         mkdir -p ${testdir} || error "mkdir failed"
16167
16168         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16169
16170         for ctr in {write,read}_bytes; do
16171                 sync
16172                 cancel_lru_locks osc
16173
16174                 do_facet ost1 $LCTL set_param -n \
16175                         "obdfilter.*.exports.clear=clear"
16176
16177                 if [ $ctr = write_bytes ]; then
16178                         f0=/dev/zero
16179                         f1=${testdir}/${tfile}
16180                 else
16181                         f0=${testdir}/${tfile}
16182                         f1=/dev/null
16183                 fi
16184
16185                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16186                         error "dd failed"
16187                 sync
16188                 cancel_lru_locks osc
16189
16190                 sum=$(do_facet ost1 $LCTL get_param \
16191                         "obdfilter.*.exports.*.stats" |
16192                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16193                                 $1 == ctr { sum += $7 }
16194                                 END { printf("%0.0f", sum) }')
16195
16196                 if ((sum != bs * count)); then
16197                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16198                 fi
16199         done
16200
16201         rm -rf $DIR/${tdir}
16202 }
16203 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16204
16205 test_133f() {
16206         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16207                 skip "too old lustre for get_param -R ($facet_ver)"
16208
16209         # verifying readability.
16210         $LCTL get_param -R '*' &> /dev/null
16211
16212         # Verifing writability with badarea_io.
16213         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16214         local skipped_params='force_lbug|changelog_mask|daemon_file'
16215         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16216                 egrep -v "$skipped_params" |
16217                 xargs -n 1 find $proc_dirs -name |
16218                 xargs -n 1 badarea_io ||
16219                 error "client badarea_io failed"
16220
16221         # remount the FS in case writes/reads /proc break the FS
16222         cleanup || error "failed to unmount"
16223         setup || error "failed to setup"
16224 }
16225 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16226
16227 test_133g() {
16228         remote_mds_nodsh && skip "remote MDS with nodsh"
16229         remote_ost_nodsh && skip "remote OST with nodsh"
16230
16231         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16232         local proc_dirs_str=$(eval echo $proc_dirs)
16233         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16234         local facet
16235         for facet in mds1 ost1; do
16236                 local facet_ver=$(lustre_version_code $facet)
16237                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16238                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16239                 else
16240                         log "$facet: too old lustre for get_param -R"
16241                 fi
16242                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16243                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16244                                 tr -d = | egrep -v $skipped_params |
16245                                 xargs -n 1 find $proc_dirs_str -name |
16246                                 xargs -n 1 badarea_io" ||
16247                                         error "$facet badarea_io failed"
16248                 else
16249                         skip_noexit "$facet: too old lustre for get_param -R"
16250                 fi
16251         done
16252
16253         # remount the FS in case writes/reads /proc break the FS
16254         cleanup || error "failed to unmount"
16255         setup || error "failed to setup"
16256 }
16257 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16258
16259 test_133h() {
16260         remote_mds_nodsh && skip "remote MDS with nodsh"
16261         remote_ost_nodsh && skip "remote OST with nodsh"
16262         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16263                 skip "Need MDS version at least 2.9.54"
16264
16265         local facet
16266         for facet in client mds1 ost1; do
16267                 # Get the list of files that are missing the terminating newline
16268                 local plist=$(do_facet $facet
16269                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16270                 local ent
16271                 for ent in $plist; do
16272                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16273                                 awk -v FS='\v' -v RS='\v\v' \
16274                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16275                                         print FILENAME}'" 2>/dev/null)
16276                         [ -z $missing ] || {
16277                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16278                                 error "file does not end with newline: $facet-$ent"
16279                         }
16280                 done
16281         done
16282 }
16283 run_test 133h "Proc files should end with newlines"
16284
16285 test_134a() {
16286         remote_mds_nodsh && skip "remote MDS with nodsh"
16287         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16288                 skip "Need MDS version at least 2.7.54"
16289
16290         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16291         cancel_lru_locks mdc
16292
16293         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16294         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16295         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16296
16297         local nr=1000
16298         createmany -o $DIR/$tdir/f $nr ||
16299                 error "failed to create $nr files in $DIR/$tdir"
16300         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16301
16302         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16303         do_facet mds1 $LCTL set_param fail_loc=0x327
16304         do_facet mds1 $LCTL set_param fail_val=500
16305         touch $DIR/$tdir/m
16306
16307         echo "sleep 10 seconds ..."
16308         sleep 10
16309         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16310
16311         do_facet mds1 $LCTL set_param fail_loc=0
16312         do_facet mds1 $LCTL set_param fail_val=0
16313         [ $lck_cnt -lt $unused ] ||
16314                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16315
16316         rm $DIR/$tdir/m
16317         unlinkmany $DIR/$tdir/f $nr
16318 }
16319 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16320
16321 test_134b() {
16322         remote_mds_nodsh && skip "remote MDS with nodsh"
16323         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16324                 skip "Need MDS version at least 2.7.54"
16325
16326         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16327         cancel_lru_locks mdc
16328
16329         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16330                         ldlm.lock_reclaim_threshold_mb)
16331         # disable reclaim temporarily
16332         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16333
16334         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16335         do_facet mds1 $LCTL set_param fail_loc=0x328
16336         do_facet mds1 $LCTL set_param fail_val=500
16337
16338         $LCTL set_param debug=+trace
16339
16340         local nr=600
16341         createmany -o $DIR/$tdir/f $nr &
16342         local create_pid=$!
16343
16344         echo "Sleep $TIMEOUT seconds ..."
16345         sleep $TIMEOUT
16346         if ! ps -p $create_pid  > /dev/null 2>&1; then
16347                 do_facet mds1 $LCTL set_param fail_loc=0
16348                 do_facet mds1 $LCTL set_param fail_val=0
16349                 do_facet mds1 $LCTL set_param \
16350                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16351                 error "createmany finished incorrectly!"
16352         fi
16353         do_facet mds1 $LCTL set_param fail_loc=0
16354         do_facet mds1 $LCTL set_param fail_val=0
16355         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16356         wait $create_pid || return 1
16357
16358         unlinkmany $DIR/$tdir/f $nr
16359 }
16360 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16361
16362 test_135() {
16363         remote_mds_nodsh && skip "remote MDS with nodsh"
16364         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16365                 skip "Need MDS version at least 2.13.50"
16366         local fname
16367
16368         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16369
16370 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16371         #set only one record at plain llog
16372         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16373
16374         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16375
16376         #fill already existed plain llog each 64767
16377         #wrapping whole catalog
16378         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16379
16380         createmany -o $DIR/$tdir/$tfile_ 64700
16381         for (( i = 0; i < 64700; i = i + 2 ))
16382         do
16383                 rm $DIR/$tdir/$tfile_$i &
16384                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16385                 local pid=$!
16386                 wait $pid
16387         done
16388
16389         #waiting osp synchronization
16390         wait_delete_completed
16391 }
16392 run_test 135 "Race catalog processing"
16393
16394 test_136() {
16395         remote_mds_nodsh && skip "remote MDS with nodsh"
16396         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16397                 skip "Need MDS version at least 2.13.50"
16398         local fname
16399
16400         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16401         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16402         #set only one record at plain llog
16403 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16404         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16405
16406         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16407
16408         #fill already existed 2 plain llogs each 64767
16409         #wrapping whole catalog
16410         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16411         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16412         wait_delete_completed
16413
16414         createmany -o $DIR/$tdir/$tfile_ 10
16415         sleep 25
16416
16417         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16418         for (( i = 0; i < 10; i = i + 3 ))
16419         do
16420                 rm $DIR/$tdir/$tfile_$i &
16421                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16422                 local pid=$!
16423                 wait $pid
16424                 sleep 7
16425                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16426         done
16427
16428         #waiting osp synchronization
16429         wait_delete_completed
16430 }
16431 run_test 136 "Race catalog processing 2"
16432
16433 test_140() { #bug-17379
16434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16435
16436         test_mkdir $DIR/$tdir
16437         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16438         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16439
16440         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16441         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16442         local i=0
16443         while i=$((i + 1)); do
16444                 test_mkdir $i
16445                 cd $i || error "Changing to $i"
16446                 ln -s ../stat stat || error "Creating stat symlink"
16447                 # Read the symlink until ELOOP present,
16448                 # not LBUGing the system is considered success,
16449                 # we didn't overrun the stack.
16450                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16451                 if [ $ret -ne 0 ]; then
16452                         if [ $ret -eq 40 ]; then
16453                                 break  # -ELOOP
16454                         else
16455                                 error "Open stat symlink"
16456                                         return
16457                         fi
16458                 fi
16459         done
16460         i=$((i - 1))
16461         echo "The symlink depth = $i"
16462         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16463                 error "Invalid symlink depth"
16464
16465         # Test recursive symlink
16466         ln -s symlink_self symlink_self
16467         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16468         echo "open symlink_self returns $ret"
16469         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16470 }
16471 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16472
16473 test_150a() {
16474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16475
16476         local TF="$TMP/$tfile"
16477
16478         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16479         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16480         cp $TF $DIR/$tfile
16481         cancel_lru_locks $OSC
16482         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16483         remount_client $MOUNT
16484         df -P $MOUNT
16485         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16486
16487         $TRUNCATE $TF 6000
16488         $TRUNCATE $DIR/$tfile 6000
16489         cancel_lru_locks $OSC
16490         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16491
16492         echo "12345" >>$TF
16493         echo "12345" >>$DIR/$tfile
16494         cancel_lru_locks $OSC
16495         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16496
16497         echo "12345" >>$TF
16498         echo "12345" >>$DIR/$tfile
16499         cancel_lru_locks $OSC
16500         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16501 }
16502 run_test 150a "truncate/append tests"
16503
16504 test_150b() {
16505         check_set_fallocate_or_skip
16506         local out
16507
16508         touch $DIR/$tfile
16509         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16510         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16511                 skip_eopnotsupp "$out|check_fallocate failed"
16512 }
16513 run_test 150b "Verify fallocate (prealloc) functionality"
16514
16515 test_150bb() {
16516         check_set_fallocate_or_skip
16517
16518         touch $DIR/$tfile
16519         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16520         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16521         > $DIR/$tfile
16522         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16523         # precomputed md5sum for 20MB of zeroes
16524         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16525         local sum=($(md5sum $DIR/$tfile))
16526
16527         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16528
16529         check_set_fallocate 1
16530
16531         > $DIR/$tfile
16532         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16533         sum=($(md5sum $DIR/$tfile))
16534
16535         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16536 }
16537 run_test 150bb "Verify fallocate modes both zero space"
16538
16539 test_150c() {
16540         check_set_fallocate_or_skip
16541         local striping="-c2"
16542
16543         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16544         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16545         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16546         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16547         local want=$((OSTCOUNT * 1048576))
16548
16549         # Must allocate all requested space, not more than 5% extra
16550         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16551                 error "bytes $bytes is not $want"
16552
16553         rm -f $DIR/$tfile
16554
16555         echo "verify fallocate on PFL file"
16556
16557         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16558
16559         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16560                 error "Create $DIR/$tfile failed"
16561         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16562         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16563         want=$((512 * 1048576))
16564
16565         # Must allocate all requested space, not more than 5% extra
16566         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16567                 error "bytes $bytes is not $want"
16568 }
16569 run_test 150c "Verify fallocate Size and Blocks"
16570
16571 test_150d() {
16572         check_set_fallocate_or_skip
16573         local striping="-c2"
16574
16575         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16576
16577         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16578         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16579                 error "setstripe failed"
16580         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16581         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16582         local want=$((OSTCOUNT * 1048576))
16583
16584         # Must allocate all requested space, not more than 5% extra
16585         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16586                 error "bytes $bytes is not $want"
16587 }
16588 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16589
16590 test_150e() {
16591         check_set_fallocate_or_skip
16592
16593         echo "df before:"
16594         $LFS df
16595         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16596         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16597                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16598
16599         # Find OST with Minimum Size
16600         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16601                        sort -un | head -1)
16602
16603         # Get 100MB per OST of the available space to reduce run time
16604         # else 60% of the available space if we are running SLOW tests
16605         if [ $SLOW == "no" ]; then
16606                 local space=$((1024 * 100 * OSTCOUNT))
16607         else
16608                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16609         fi
16610
16611         fallocate -l${space}k $DIR/$tfile ||
16612                 error "fallocate ${space}k $DIR/$tfile failed"
16613         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16614
16615         # get size immediately after fallocate. This should be correctly
16616         # updated
16617         local size=$(stat -c '%s' $DIR/$tfile)
16618         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16619
16620         # Sleep for a while for statfs to get updated. And not pull from cache.
16621         sleep 2
16622
16623         echo "df after fallocate:"
16624         $LFS df
16625
16626         (( size / 1024 == space )) || error "size $size != requested $space"
16627         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16628                 error "used $used < space $space"
16629
16630         rm $DIR/$tfile || error "rm failed"
16631         sync
16632         wait_delete_completed
16633
16634         echo "df after unlink:"
16635         $LFS df
16636 }
16637 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16638
16639 test_150f() {
16640         local size
16641         local blocks
16642         local want_size_before=20480 # in bytes
16643         local want_blocks_before=40 # 512 sized blocks
16644         local want_blocks_after=24  # 512 sized blocks
16645         local length=$(((want_blocks_before - want_blocks_after) * 512))
16646
16647         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16648                 skip "need at least 2.14.0 for fallocate punch"
16649
16650         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16651                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16652         fi
16653
16654         check_set_fallocate_or_skip
16655         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16656
16657         [[ "x$DOM" == "xyes" ]] &&
16658                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16659
16660         echo "Verify fallocate punch: Range within the file range"
16661         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16662                 error "dd failed for bs 4096 and count 5"
16663
16664         # Call fallocate with punch range which is within the file range
16665         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16666                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16667         # client must see changes immediately after fallocate
16668         size=$(stat -c '%s' $DIR/$tfile)
16669         blocks=$(stat -c '%b' $DIR/$tfile)
16670
16671         # Verify punch worked.
16672         (( blocks == want_blocks_after )) ||
16673                 error "punch failed: blocks $blocks != $want_blocks_after"
16674
16675         (( size == want_size_before )) ||
16676                 error "punch failed: size $size != $want_size_before"
16677
16678         # Verify there is hole in file
16679         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16680         # precomputed md5sum
16681         local expect="4a9a834a2db02452929c0a348273b4aa"
16682
16683         cksum=($(md5sum $DIR/$tfile))
16684         [[ "${cksum[0]}" == "$expect" ]] ||
16685                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16686
16687         # Start second sub-case for fallocate punch.
16688         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16689         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16690                 error "dd failed for bs 4096 and count 5"
16691
16692         # Punch range less than block size will have no change in block count
16693         want_blocks_after=40  # 512 sized blocks
16694
16695         # Punch overlaps two blocks and less than blocksize
16696         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16697                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16698         size=$(stat -c '%s' $DIR/$tfile)
16699         blocks=$(stat -c '%b' $DIR/$tfile)
16700
16701         # Verify punch worked.
16702         (( blocks == want_blocks_after )) ||
16703                 error "punch failed: blocks $blocks != $want_blocks_after"
16704
16705         (( size == want_size_before )) ||
16706                 error "punch failed: size $size != $want_size_before"
16707
16708         # Verify if range is really zero'ed out. We expect Zeros.
16709         # precomputed md5sum
16710         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16711         cksum=($(md5sum $DIR/$tfile))
16712         [[ "${cksum[0]}" == "$expect" ]] ||
16713                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16714 }
16715 run_test 150f "Verify fallocate punch functionality"
16716
16717 test_150g() {
16718         local space
16719         local size
16720         local blocks
16721         local blocks_after
16722         local size_after
16723         local BS=4096 # Block size in bytes
16724
16725         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16726                 skip "need at least 2.14.0 for fallocate punch"
16727
16728         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16729                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16730         fi
16731
16732         check_set_fallocate_or_skip
16733         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16734
16735         if [[ "x$DOM" == "xyes" ]]; then
16736                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16737                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16738         else
16739                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16740                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16741         fi
16742
16743         # Get 100MB per OST of the available space to reduce run time
16744         # else 60% of the available space if we are running SLOW tests
16745         if [ $SLOW == "no" ]; then
16746                 space=$((1024 * 100 * OSTCOUNT))
16747         else
16748                 # Find OST with Minimum Size
16749                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16750                         sort -un | head -1)
16751                 echo "min size OST: $space"
16752                 space=$(((space * 60)/100 * OSTCOUNT))
16753         fi
16754         # space in 1k units, round to 4k blocks
16755         local blkcount=$((space * 1024 / $BS))
16756
16757         echo "Verify fallocate punch: Very large Range"
16758         fallocate -l${space}k $DIR/$tfile ||
16759                 error "fallocate ${space}k $DIR/$tfile failed"
16760         # write 1M at the end, start and in the middle
16761         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16762                 error "dd failed: bs $BS count 256"
16763         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16764                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16765         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16766                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16767
16768         # Gather stats.
16769         size=$(stat -c '%s' $DIR/$tfile)
16770
16771         # gather punch length.
16772         local punch_size=$((size - (BS * 2)))
16773
16774         echo "punch_size = $punch_size"
16775         echo "size - punch_size: $((size - punch_size))"
16776         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16777
16778         # Call fallocate to punch all except 2 blocks. We leave the
16779         # first and the last block
16780         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16781         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16782                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16783
16784         size_after=$(stat -c '%s' $DIR/$tfile)
16785         blocks_after=$(stat -c '%b' $DIR/$tfile)
16786
16787         # Verify punch worked.
16788         # Size should be kept
16789         (( size == size_after )) ||
16790                 error "punch failed: size $size != $size_after"
16791
16792         # two 4k data blocks to remain plus possible 1 extra extent block
16793         (( blocks_after <= ((BS / 512) * 3) )) ||
16794                 error "too many blocks remains: $blocks_after"
16795
16796         # Verify that file has hole between the first and the last blocks
16797         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16798         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16799
16800         echo "Hole at [$hole_start, $hole_end)"
16801         (( hole_start == BS )) ||
16802                 error "no hole at offset $BS after punch"
16803
16804         (( hole_end == BS + punch_size )) ||
16805                 error "data at offset $hole_end < $((BS + punch_size))"
16806 }
16807 run_test 150g "Verify fallocate punch on large range"
16808
16809 test_150h() {
16810         local file=$DIR/$tfile
16811         local size
16812
16813         check_set_fallocate_or_skip
16814         statx_supported || skip_env "Test must be statx() syscall supported"
16815
16816         # fallocate() does not update the size information on the MDT
16817         fallocate -l 16K $file || error "failed to fallocate $file"
16818         cancel_lru_locks $OSC
16819         # STATX with cached-always mode will not send glimpse RPCs to OST,
16820         # it uses the caching attrs on the client side as much as possible.
16821         size=$($STATX --cached=always -c %s $file)
16822         [ $size == 16384 ] ||
16823                 error "size after fallocate() is $size, expected 16384"
16824 }
16825 run_test 150h "Verify extend fallocate updates the file size"
16826
16827 #LU-2902 roc_hit was not able to read all values from lproc
16828 function roc_hit_init() {
16829         local list=$(comma_list $(osts_nodes))
16830         local dir=$DIR/$tdir-check
16831         local file=$dir/$tfile
16832         local BEFORE
16833         local AFTER
16834         local idx
16835
16836         test_mkdir $dir
16837         #use setstripe to do a write to every ost
16838         for i in $(seq 0 $((OSTCOUNT-1))); do
16839                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16840                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16841                 idx=$(printf %04x $i)
16842                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16843                         awk '$1 == "cache_access" {sum += $7}
16844                                 END { printf("%0.0f", sum) }')
16845
16846                 cancel_lru_locks osc
16847                 cat $file >/dev/null
16848
16849                 AFTER=$(get_osd_param $list *OST*$idx stats |
16850                         awk '$1 == "cache_access" {sum += $7}
16851                                 END { printf("%0.0f", sum) }')
16852
16853                 echo BEFORE:$BEFORE AFTER:$AFTER
16854                 if ! let "AFTER - BEFORE == 4"; then
16855                         rm -rf $dir
16856                         error "roc_hit is not safe to use"
16857                 fi
16858                 rm $file
16859         done
16860
16861         rm -rf $dir
16862 }
16863
16864 function roc_hit() {
16865         local list=$(comma_list $(osts_nodes))
16866         echo $(get_osd_param $list '' stats |
16867                 awk '$1 == "cache_hit" {sum += $7}
16868                         END { printf("%0.0f", sum) }')
16869 }
16870
16871 function set_cache() {
16872         local on=1
16873
16874         if [ "$2" == "off" ]; then
16875                 on=0;
16876         fi
16877         local list=$(comma_list $(osts_nodes))
16878         set_osd_param $list '' $1_cache_enable $on
16879
16880         cancel_lru_locks osc
16881 }
16882
16883 test_151() {
16884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16885         remote_ost_nodsh && skip "remote OST with nodsh"
16886         (( CLIENT_VERSION == OST1_VERSION )) ||
16887                 skip "LU-13081: no interop testing for OSS cache"
16888
16889         local CPAGES=3
16890         local list=$(comma_list $(osts_nodes))
16891
16892         # check whether obdfilter is cache capable at all
16893         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16894                 skip "not cache-capable obdfilter"
16895         fi
16896
16897         # check cache is enabled on all obdfilters
16898         if get_osd_param $list '' read_cache_enable | grep 0; then
16899                 skip "oss cache is disabled"
16900         fi
16901
16902         set_osd_param $list '' writethrough_cache_enable 1
16903
16904         # check write cache is enabled on all obdfilters
16905         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16906                 skip "oss write cache is NOT enabled"
16907         fi
16908
16909         roc_hit_init
16910
16911         #define OBD_FAIL_OBD_NO_LRU  0x609
16912         do_nodes $list $LCTL set_param fail_loc=0x609
16913
16914         # pages should be in the case right after write
16915         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16916                 error "dd failed"
16917
16918         local BEFORE=$(roc_hit)
16919         cancel_lru_locks osc
16920         cat $DIR/$tfile >/dev/null
16921         local AFTER=$(roc_hit)
16922
16923         do_nodes $list $LCTL set_param fail_loc=0
16924
16925         if ! let "AFTER - BEFORE == CPAGES"; then
16926                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16927         fi
16928
16929         cancel_lru_locks osc
16930         # invalidates OST cache
16931         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16932         set_osd_param $list '' read_cache_enable 0
16933         cat $DIR/$tfile >/dev/null
16934
16935         # now data shouldn't be found in the cache
16936         BEFORE=$(roc_hit)
16937         cancel_lru_locks osc
16938         cat $DIR/$tfile >/dev/null
16939         AFTER=$(roc_hit)
16940         if let "AFTER - BEFORE != 0"; then
16941                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16942         fi
16943
16944         set_osd_param $list '' read_cache_enable 1
16945         rm -f $DIR/$tfile
16946 }
16947 run_test 151 "test cache on oss and controls ==============================="
16948
16949 test_152() {
16950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16951
16952         local TF="$TMP/$tfile"
16953
16954         # simulate ENOMEM during write
16955 #define OBD_FAIL_OST_NOMEM      0x226
16956         lctl set_param fail_loc=0x80000226
16957         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16958         cp $TF $DIR/$tfile
16959         sync || error "sync failed"
16960         lctl set_param fail_loc=0
16961
16962         # discard client's cache
16963         cancel_lru_locks osc
16964
16965         # simulate ENOMEM during read
16966         lctl set_param fail_loc=0x80000226
16967         cmp $TF $DIR/$tfile || error "cmp failed"
16968         lctl set_param fail_loc=0
16969
16970         rm -f $TF
16971 }
16972 run_test 152 "test read/write with enomem ============================"
16973
16974 test_153() {
16975         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16976 }
16977 run_test 153 "test if fdatasync does not crash ======================="
16978
16979 dot_lustre_fid_permission_check() {
16980         local fid=$1
16981         local ffid=$MOUNT/.lustre/fid/$fid
16982         local test_dir=$2
16983
16984         echo "stat fid $fid"
16985         stat $ffid || error "stat $ffid failed."
16986         echo "touch fid $fid"
16987         touch $ffid || error "touch $ffid failed."
16988         echo "write to fid $fid"
16989         cat /etc/hosts > $ffid || error "write $ffid failed."
16990         echo "read fid $fid"
16991         diff /etc/hosts $ffid || error "read $ffid failed."
16992         echo "append write to fid $fid"
16993         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16994         echo "rename fid $fid"
16995         mv $ffid $test_dir/$tfile.1 &&
16996                 error "rename $ffid to $tfile.1 should fail."
16997         touch $test_dir/$tfile.1
16998         mv $test_dir/$tfile.1 $ffid &&
16999                 error "rename $tfile.1 to $ffid should fail."
17000         rm -f $test_dir/$tfile.1
17001         echo "truncate fid $fid"
17002         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
17003         echo "link fid $fid"
17004         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
17005         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
17006                 id $USER0 || skip_env "missing user $USER0"
17007                 echo "setfacl fid $fid"
17008                 setfacl -R -m u:$USER0:rwx $ffid ||
17009                         error "setfacl $ffid failed"
17010                 echo "getfacl fid $fid"
17011                 getfacl $ffid || error "getfacl $ffid failed."
17012         fi
17013         echo "unlink fid $fid"
17014         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
17015         echo "mknod fid $fid"
17016         mknod $ffid c 1 3 && error "mknod $ffid should fail."
17017
17018         fid=[0xf00000400:0x1:0x0]
17019         ffid=$MOUNT/.lustre/fid/$fid
17020
17021         echo "stat non-exist fid $fid"
17022         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
17023         echo "write to non-exist fid $fid"
17024         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
17025         echo "link new fid $fid"
17026         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
17027
17028         mkdir -p $test_dir/$tdir
17029         touch $test_dir/$tdir/$tfile
17030         fid=$($LFS path2fid $test_dir/$tdir)
17031         rc=$?
17032         [ $rc -ne 0 ] &&
17033                 error "error: could not get fid for $test_dir/$dir/$tfile."
17034
17035         ffid=$MOUNT/.lustre/fid/$fid
17036
17037         echo "ls $fid"
17038         ls $ffid || error "ls $ffid failed."
17039         echo "touch $fid/$tfile.1"
17040         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17041
17042         echo "touch $MOUNT/.lustre/fid/$tfile"
17043         touch $MOUNT/.lustre/fid/$tfile && \
17044                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17045
17046         echo "setxattr to $MOUNT/.lustre/fid"
17047         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17048
17049         echo "listxattr for $MOUNT/.lustre/fid"
17050         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17051
17052         echo "delxattr from $MOUNT/.lustre/fid"
17053         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17054
17055         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17056         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17057                 error "touch invalid fid should fail."
17058
17059         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17060         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17061                 error "touch non-normal fid should fail."
17062
17063         echo "rename $tdir to $MOUNT/.lustre/fid"
17064         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17065                 error "rename to $MOUNT/.lustre/fid should fail."
17066
17067         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17068         then            # LU-3547
17069                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17070                 local new_obf_mode=777
17071
17072                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17073                 chmod $new_obf_mode $DIR/.lustre/fid ||
17074                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17075
17076                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17077                 [ $obf_mode -eq $new_obf_mode ] ||
17078                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17079
17080                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17081                 chmod $old_obf_mode $DIR/.lustre/fid ||
17082                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17083         fi
17084
17085         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17086         fid=$($LFS path2fid $test_dir/$tfile-2)
17087
17088         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17089         then # LU-5424
17090                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17091                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17092                         error "create lov data thru .lustre failed"
17093         fi
17094         echo "cp /etc/passwd $test_dir/$tfile-2"
17095         cp /etc/passwd $test_dir/$tfile-2 ||
17096                 error "copy to $test_dir/$tfile-2 failed."
17097         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17098         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17099                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17100
17101         rm -rf $test_dir/tfile.lnk
17102         rm -rf $test_dir/$tfile-2
17103 }
17104
17105 test_154A() {
17106         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17107                 skip "Need MDS version at least 2.4.1"
17108
17109         local tf=$DIR/$tfile
17110         touch $tf
17111
17112         local fid=$($LFS path2fid $tf)
17113         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17114
17115         # check that we get the same pathname back
17116         local rootpath
17117         local found
17118         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17119                 echo "$rootpath $fid"
17120                 found=$($LFS fid2path $rootpath "$fid")
17121                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17122                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17123         done
17124
17125         # check wrong root path format
17126         rootpath=$MOUNT"_wrong"
17127         found=$($LFS fid2path $rootpath "$fid")
17128         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17129 }
17130 run_test 154A "lfs path2fid and fid2path basic checks"
17131
17132 test_154B() {
17133         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17134                 skip "Need MDS version at least 2.4.1"
17135
17136         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17137         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17138         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17139         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17140
17141         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17142         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17143
17144         # check that we get the same pathname
17145         echo "PFID: $PFID, name: $name"
17146         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17147         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17148         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17149                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17150
17151         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17152 }
17153 run_test 154B "verify the ll_decode_linkea tool"
17154
17155 test_154a() {
17156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17157         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17158         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17159                 skip "Need MDS version at least 2.2.51"
17160         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17161
17162         cp /etc/hosts $DIR/$tfile
17163
17164         fid=$($LFS path2fid $DIR/$tfile)
17165         rc=$?
17166         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17167
17168         dot_lustre_fid_permission_check "$fid" $DIR ||
17169                 error "dot lustre permission check $fid failed"
17170
17171         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17172
17173         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17174
17175         touch $MOUNT/.lustre/file &&
17176                 error "creation is not allowed under .lustre"
17177
17178         mkdir $MOUNT/.lustre/dir &&
17179                 error "mkdir is not allowed under .lustre"
17180
17181         rm -rf $DIR/$tfile
17182 }
17183 run_test 154a "Open-by-FID"
17184
17185 test_154b() {
17186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17187         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17188         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17189         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17190                 skip "Need MDS version at least 2.2.51"
17191
17192         local remote_dir=$DIR/$tdir/remote_dir
17193         local MDTIDX=1
17194         local rc=0
17195
17196         mkdir -p $DIR/$tdir
17197         $LFS mkdir -i $MDTIDX $remote_dir ||
17198                 error "create remote directory failed"
17199
17200         cp /etc/hosts $remote_dir/$tfile
17201
17202         fid=$($LFS path2fid $remote_dir/$tfile)
17203         rc=$?
17204         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17205
17206         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17207                 error "dot lustre permission check $fid failed"
17208         rm -rf $DIR/$tdir
17209 }
17210 run_test 154b "Open-by-FID for remote directory"
17211
17212 test_154c() {
17213         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17214                 skip "Need MDS version at least 2.4.1"
17215
17216         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17217         local FID1=$($LFS path2fid $DIR/$tfile.1)
17218         local FID2=$($LFS path2fid $DIR/$tfile.2)
17219         local FID3=$($LFS path2fid $DIR/$tfile.3)
17220
17221         local N=1
17222         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17223                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17224                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17225                 local want=FID$N
17226                 [ "$FID" = "${!want}" ] ||
17227                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17228                 N=$((N + 1))
17229         done
17230
17231         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17232         do
17233                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17234                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17235                 N=$((N + 1))
17236         done
17237 }
17238 run_test 154c "lfs path2fid and fid2path multiple arguments"
17239
17240 test_154d() {
17241         remote_mds_nodsh && skip "remote MDS with nodsh"
17242         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17243                 skip "Need MDS version at least 2.5.53"
17244
17245         if remote_mds; then
17246                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17247         else
17248                 nid="0@lo"
17249         fi
17250         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17251         local fd
17252         local cmd
17253
17254         rm -f $DIR/$tfile
17255         touch $DIR/$tfile
17256
17257         local fid=$($LFS path2fid $DIR/$tfile)
17258         # Open the file
17259         fd=$(free_fd)
17260         cmd="exec $fd<$DIR/$tfile"
17261         eval $cmd
17262         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17263         echo "$fid_list" | grep "$fid"
17264         rc=$?
17265
17266         cmd="exec $fd>/dev/null"
17267         eval $cmd
17268         if [ $rc -ne 0 ]; then
17269                 error "FID $fid not found in open files list $fid_list"
17270         fi
17271 }
17272 run_test 154d "Verify open file fid"
17273
17274 test_154e()
17275 {
17276         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17277                 skip "Need MDS version at least 2.6.50"
17278
17279         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17280                 error ".lustre returned by readdir"
17281         fi
17282 }
17283 run_test 154e ".lustre is not returned by readdir"
17284
17285 test_154f() {
17286         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17287
17288         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17289         mkdir_on_mdt0 $DIR/$tdir
17290         # test dirs inherit from its stripe
17291         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17292         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17293         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17294         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17295         touch $DIR/f
17296
17297         # get fid of parents
17298         local FID0=$($LFS path2fid $DIR/$tdir)
17299         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17300         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17301         local FID3=$($LFS path2fid $DIR)
17302
17303         # check that path2fid --parents returns expected <parent_fid>/name
17304         # 1) test for a directory (single parent)
17305         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17306         [ "$parent" == "$FID0/foo1" ] ||
17307                 error "expected parent: $FID0/foo1, got: $parent"
17308
17309         # 2) test for a file with nlink > 1 (multiple parents)
17310         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17311         echo "$parent" | grep -F "$FID1/$tfile" ||
17312                 error "$FID1/$tfile not returned in parent list"
17313         echo "$parent" | grep -F "$FID2/link" ||
17314                 error "$FID2/link not returned in parent list"
17315
17316         # 3) get parent by fid
17317         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17318         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17319         echo "$parent" | grep -F "$FID1/$tfile" ||
17320                 error "$FID1/$tfile not returned in parent list (by fid)"
17321         echo "$parent" | grep -F "$FID2/link" ||
17322                 error "$FID2/link not returned in parent list (by fid)"
17323
17324         # 4) test for entry in root directory
17325         parent=$($LFS path2fid --parents $DIR/f)
17326         echo "$parent" | grep -F "$FID3/f" ||
17327                 error "$FID3/f not returned in parent list"
17328
17329         # 5) test it on root directory
17330         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17331                 error "$MOUNT should not have parents"
17332
17333         # enable xattr caching and check that linkea is correctly updated
17334         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17335         save_lustre_params client "llite.*.xattr_cache" > $save
17336         lctl set_param llite.*.xattr_cache 1
17337
17338         # 6.1) linkea update on rename
17339         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17340
17341         # get parents by fid
17342         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17343         # foo1 should no longer be returned in parent list
17344         echo "$parent" | grep -F "$FID1" &&
17345                 error "$FID1 should no longer be in parent list"
17346         # the new path should appear
17347         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17348                 error "$FID2/$tfile.moved is not in parent list"
17349
17350         # 6.2) linkea update on unlink
17351         rm -f $DIR/$tdir/foo2/link
17352         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17353         # foo2/link should no longer be returned in parent list
17354         echo "$parent" | grep -F "$FID2/link" &&
17355                 error "$FID2/link should no longer be in parent list"
17356         true
17357
17358         rm -f $DIR/f
17359         restore_lustre_params < $save
17360         rm -f $save
17361 }
17362 run_test 154f "get parent fids by reading link ea"
17363
17364 test_154g()
17365 {
17366         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17367            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17368                 skip "Need MDS version at least 2.6.92"
17369
17370         mkdir_on_mdt0 $DIR/$tdir
17371         llapi_fid_test -d $DIR/$tdir
17372 }
17373 run_test 154g "various llapi FID tests"
17374
17375 test_154h()
17376 {
17377         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17378                 skip "Need client at least version 2.15.55.1"
17379
17380         # Create an empty file
17381         touch $DIR/$tfile
17382
17383         # Get FID (interactive mode) and save under $TMP/$tfile.log
17384         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17385                 path2fid $DIR/$tfile
17386         EOF
17387
17388         fid=$(cat $TMP/$tfile.log)
17389         # $fid should not be empty
17390         [[ ! -z $fid ]] || error "FID is empty"
17391         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17392 }
17393 run_test 154h "Verify interactive path2fid"
17394
17395 test_155_small_load() {
17396     local temp=$TMP/$tfile
17397     local file=$DIR/$tfile
17398
17399     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17400         error "dd of=$temp bs=6096 count=1 failed"
17401     cp $temp $file
17402     cancel_lru_locks $OSC
17403     cmp $temp $file || error "$temp $file differ"
17404
17405     $TRUNCATE $temp 6000
17406     $TRUNCATE $file 6000
17407     cmp $temp $file || error "$temp $file differ (truncate1)"
17408
17409     echo "12345" >>$temp
17410     echo "12345" >>$file
17411     cmp $temp $file || error "$temp $file differ (append1)"
17412
17413     echo "12345" >>$temp
17414     echo "12345" >>$file
17415     cmp $temp $file || error "$temp $file differ (append2)"
17416
17417     rm -f $temp $file
17418     true
17419 }
17420
17421 test_155_big_load() {
17422         remote_ost_nodsh && skip "remote OST with nodsh"
17423
17424         local temp=$TMP/$tfile
17425         local file=$DIR/$tfile
17426
17427         free_min_max
17428         local cache_size=$(do_facet ost$((MAXI+1)) \
17429                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17430
17431         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17432         # pre-set value
17433         if [ -z "$cache_size" ]; then
17434                 cache_size=256
17435         fi
17436         local large_file_size=$((cache_size * 2))
17437
17438         echo "OSS cache size: $cache_size KB"
17439         echo "Large file size: $large_file_size KB"
17440
17441         [ $MAXV -le $large_file_size ] &&
17442                 skip_env "max available OST size needs > $large_file_size KB"
17443
17444         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17445
17446         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17447                 error "dd of=$temp bs=$large_file_size count=1k failed"
17448         cp $temp $file
17449         ls -lh $temp $file
17450         cancel_lru_locks osc
17451         cmp $temp $file || error "$temp $file differ"
17452
17453         rm -f $temp $file
17454         true
17455 }
17456
17457 save_writethrough() {
17458         local facets=$(get_facets OST)
17459
17460         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17461 }
17462
17463 test_155a() {
17464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17465
17466         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17467
17468         save_writethrough $p
17469
17470         set_cache read on
17471         set_cache writethrough on
17472         test_155_small_load
17473         restore_lustre_params < $p
17474         rm -f $p
17475 }
17476 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17477
17478 test_155b() {
17479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17480
17481         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17482
17483         save_writethrough $p
17484
17485         set_cache read on
17486         set_cache writethrough off
17487         test_155_small_load
17488         restore_lustre_params < $p
17489         rm -f $p
17490 }
17491 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17492
17493 test_155c() {
17494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17495
17496         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17497
17498         save_writethrough $p
17499
17500         set_cache read off
17501         set_cache writethrough on
17502         test_155_small_load
17503         restore_lustre_params < $p
17504         rm -f $p
17505 }
17506 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17507
17508 test_155d() {
17509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17510
17511         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17512
17513         save_writethrough $p
17514
17515         set_cache read off
17516         set_cache writethrough off
17517         test_155_small_load
17518         restore_lustre_params < $p
17519         rm -f $p
17520 }
17521 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17522
17523 test_155e() {
17524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17525
17526         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17527
17528         save_writethrough $p
17529
17530         set_cache read on
17531         set_cache writethrough on
17532         test_155_big_load
17533         restore_lustre_params < $p
17534         rm -f $p
17535 }
17536 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17537
17538 test_155f() {
17539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17540
17541         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17542
17543         save_writethrough $p
17544
17545         set_cache read on
17546         set_cache writethrough off
17547         test_155_big_load
17548         restore_lustre_params < $p
17549         rm -f $p
17550 }
17551 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17552
17553 test_155g() {
17554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17555
17556         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17557
17558         save_writethrough $p
17559
17560         set_cache read off
17561         set_cache writethrough on
17562         test_155_big_load
17563         restore_lustre_params < $p
17564         rm -f $p
17565 }
17566 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17567
17568 test_155h() {
17569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17570
17571         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17572
17573         save_writethrough $p
17574
17575         set_cache read off
17576         set_cache writethrough off
17577         test_155_big_load
17578         restore_lustre_params < $p
17579         rm -f $p
17580 }
17581 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17582
17583 test_156() {
17584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17585         remote_ost_nodsh && skip "remote OST with nodsh"
17586         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17587                 skip "stats not implemented on old servers"
17588         [ "$ost1_FSTYPE" = "zfs" ] &&
17589                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17590         (( CLIENT_VERSION == OST1_VERSION )) ||
17591                 skip "LU-13081: no interop testing for OSS cache"
17592
17593         local CPAGES=3
17594         local BEFORE
17595         local AFTER
17596         local file="$DIR/$tfile"
17597         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17598
17599         save_writethrough $p
17600         roc_hit_init
17601
17602         log "Turn on read and write cache"
17603         set_cache read on
17604         set_cache writethrough on
17605
17606         log "Write data and read it back."
17607         log "Read should be satisfied from the cache."
17608         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17609         BEFORE=$(roc_hit)
17610         cancel_lru_locks osc
17611         cat $file >/dev/null
17612         AFTER=$(roc_hit)
17613         if ! let "AFTER - BEFORE == CPAGES"; then
17614                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17615         else
17616                 log "cache hits: before: $BEFORE, after: $AFTER"
17617         fi
17618
17619         log "Read again; it should be satisfied from the cache."
17620         BEFORE=$AFTER
17621         cancel_lru_locks osc
17622         cat $file >/dev/null
17623         AFTER=$(roc_hit)
17624         if ! let "AFTER - BEFORE == CPAGES"; then
17625                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17626         else
17627                 log "cache hits:: before: $BEFORE, after: $AFTER"
17628         fi
17629
17630         log "Turn off the read cache and turn on the write cache"
17631         set_cache read off
17632         set_cache writethrough on
17633
17634         log "Read again; it should be satisfied from the cache."
17635         BEFORE=$(roc_hit)
17636         cancel_lru_locks osc
17637         cat $file >/dev/null
17638         AFTER=$(roc_hit)
17639         if ! let "AFTER - BEFORE == CPAGES"; then
17640                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17641         else
17642                 log "cache hits:: before: $BEFORE, after: $AFTER"
17643         fi
17644
17645         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17646                 # > 2.12.56 uses pagecache if cached
17647                 log "Read again; it should not be satisfied from the cache."
17648                 BEFORE=$AFTER
17649                 cancel_lru_locks osc
17650                 cat $file >/dev/null
17651                 AFTER=$(roc_hit)
17652                 if ! let "AFTER - BEFORE == 0"; then
17653                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17654                 else
17655                         log "cache hits:: before: $BEFORE, after: $AFTER"
17656                 fi
17657         fi
17658
17659         log "Write data and read it back."
17660         log "Read should be satisfied from the cache."
17661         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17662         BEFORE=$(roc_hit)
17663         cancel_lru_locks osc
17664         cat $file >/dev/null
17665         AFTER=$(roc_hit)
17666         if ! let "AFTER - BEFORE == CPAGES"; then
17667                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17668         else
17669                 log "cache hits:: before: $BEFORE, after: $AFTER"
17670         fi
17671
17672         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17673                 # > 2.12.56 uses pagecache if cached
17674                 log "Read again; it should not be satisfied from the cache."
17675                 BEFORE=$AFTER
17676                 cancel_lru_locks osc
17677                 cat $file >/dev/null
17678                 AFTER=$(roc_hit)
17679                 if ! let "AFTER - BEFORE == 0"; then
17680                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17681                 else
17682                         log "cache hits:: before: $BEFORE, after: $AFTER"
17683                 fi
17684         fi
17685
17686         log "Turn off read and write cache"
17687         set_cache read off
17688         set_cache writethrough off
17689
17690         log "Write data and read it back"
17691         log "It should not be satisfied from the cache."
17692         rm -f $file
17693         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17694         cancel_lru_locks osc
17695         BEFORE=$(roc_hit)
17696         cat $file >/dev/null
17697         AFTER=$(roc_hit)
17698         if ! let "AFTER - BEFORE == 0"; then
17699                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17700         else
17701                 log "cache hits:: before: $BEFORE, after: $AFTER"
17702         fi
17703
17704         log "Turn on the read cache and turn off the write cache"
17705         set_cache read on
17706         set_cache writethrough off
17707
17708         log "Write data and read it back"
17709         log "It should not be satisfied from the cache."
17710         rm -f $file
17711         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17712         BEFORE=$(roc_hit)
17713         cancel_lru_locks osc
17714         cat $file >/dev/null
17715         AFTER=$(roc_hit)
17716         if ! let "AFTER - BEFORE == 0"; then
17717                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17718         else
17719                 log "cache hits:: before: $BEFORE, after: $AFTER"
17720         fi
17721
17722         log "Read again; it should be satisfied from the cache."
17723         BEFORE=$(roc_hit)
17724         cancel_lru_locks osc
17725         cat $file >/dev/null
17726         AFTER=$(roc_hit)
17727         if ! let "AFTER - BEFORE == CPAGES"; then
17728                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17729         else
17730                 log "cache hits:: before: $BEFORE, after: $AFTER"
17731         fi
17732
17733         restore_lustre_params < $p
17734         rm -f $p $file
17735 }
17736 run_test 156 "Verification of tunables"
17737
17738 test_160a() {
17739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17740         remote_mds_nodsh && skip "remote MDS with nodsh"
17741         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17742                 skip "Need MDS version at least 2.2.0"
17743
17744         changelog_register || error "changelog_register failed"
17745         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17746         changelog_users $SINGLEMDS | grep -q $cl_user ||
17747                 error "User $cl_user not found in changelog_users"
17748
17749         mkdir_on_mdt0 $DIR/$tdir
17750
17751         # change something
17752         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17753         changelog_clear 0 || error "changelog_clear failed"
17754         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17755         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17756         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17757         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17758         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17759         rm $DIR/$tdir/pics/desktop.jpg
17760
17761         echo "verifying changelog mask"
17762         changelog_chmask "-MKDIR"
17763         changelog_chmask "-CLOSE"
17764
17765         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17766         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17767
17768         changelog_chmask "+MKDIR"
17769         changelog_chmask "+CLOSE"
17770
17771         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17772         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17773
17774         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17775         CLOSES=$(changelog_dump | grep -c "CLOSE")
17776         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17777         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17778
17779         # verify contents
17780         echo "verifying target fid"
17781         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17782         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17783         [ "$fidc" == "$fidf" ] ||
17784                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17785         echo "verifying parent fid"
17786         # The FID returned from the Changelog may be the directory shard on
17787         # a different MDT, and not the FID returned by path2fid on the parent.
17788         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17789         # since this is what will matter when recreating this file in the tree.
17790         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17791         local pathp=$($LFS fid2path $MOUNT "$fidp")
17792         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17793                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17794
17795         echo "getting records for $cl_user"
17796         changelog_users $SINGLEMDS
17797         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17798         local nclr=3
17799         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17800                 error "changelog_clear failed"
17801         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17802         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17803         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17804                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17805
17806         local min0_rec=$(changelog_users $SINGLEMDS |
17807                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17808         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17809                           awk '{ print $1; exit; }')
17810
17811         changelog_dump | tail -n 5
17812         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17813         [ $first_rec == $((min0_rec + 1)) ] ||
17814                 error "first index should be $min0_rec + 1 not $first_rec"
17815
17816         # LU-3446 changelog index reset on MDT restart
17817         local cur_rec1=$(changelog_users $SINGLEMDS |
17818                          awk '/^current.index:/ { print $NF }')
17819         changelog_clear 0 ||
17820                 error "clear all changelog records for $cl_user failed"
17821         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17822         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17823                 error "Fail to start $SINGLEMDS"
17824         local cur_rec2=$(changelog_users $SINGLEMDS |
17825                          awk '/^current.index:/ { print $NF }')
17826         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17827         [ $cur_rec1 == $cur_rec2 ] ||
17828                 error "current index should be $cur_rec1 not $cur_rec2"
17829
17830         echo "verifying users from this test are deregistered"
17831         changelog_deregister || error "changelog_deregister failed"
17832         changelog_users $SINGLEMDS | grep -q $cl_user &&
17833                 error "User '$cl_user' still in changelog_users"
17834
17835         # lctl get_param -n mdd.*.changelog_users
17836         # current_index: 144
17837         # ID    index (idle seconds)
17838         # cl3   144   (2) mask=<list>
17839         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17840                 # this is the normal case where all users were deregistered
17841                 # make sure no new records are added when no users are present
17842                 local last_rec1=$(changelog_users $SINGLEMDS |
17843                                   awk '/^current.index:/ { print $NF }')
17844                 touch $DIR/$tdir/chloe
17845                 local last_rec2=$(changelog_users $SINGLEMDS |
17846                                   awk '/^current.index:/ { print $NF }')
17847                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17848                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17849         else
17850                 # any changelog users must be leftovers from a previous test
17851                 changelog_users $SINGLEMDS
17852                 echo "other changelog users; can't verify off"
17853         fi
17854 }
17855 run_test 160a "changelog sanity"
17856
17857 test_160b() { # LU-3587
17858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17859         remote_mds_nodsh && skip "remote MDS with nodsh"
17860         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17861                 skip "Need MDS version at least 2.2.0"
17862
17863         changelog_register || error "changelog_register failed"
17864         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17865         changelog_users $SINGLEMDS | grep -q $cl_user ||
17866                 error "User '$cl_user' not found in changelog_users"
17867
17868         local longname1=$(str_repeat a 255)
17869         local longname2=$(str_repeat b 255)
17870
17871         cd $DIR
17872         echo "creating very long named file"
17873         touch $longname1 || error "create of '$longname1' failed"
17874         echo "renaming very long named file"
17875         mv $longname1 $longname2
17876
17877         changelog_dump | grep RENME | tail -n 5
17878         rm -f $longname2
17879 }
17880 run_test 160b "Verify that very long rename doesn't crash in changelog"
17881
17882 test_160c() {
17883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17884         remote_mds_nodsh && skip "remote MDS with nodsh"
17885
17886         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17887                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17888                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17889                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17890
17891         local rc=0
17892
17893         # Registration step
17894         changelog_register || error "changelog_register failed"
17895
17896         rm -rf $DIR/$tdir
17897         mkdir -p $DIR/$tdir
17898         $MCREATE $DIR/$tdir/foo_160c
17899         changelog_chmask "-TRUNC"
17900         $TRUNCATE $DIR/$tdir/foo_160c 200
17901         changelog_chmask "+TRUNC"
17902         $TRUNCATE $DIR/$tdir/foo_160c 199
17903         changelog_dump | tail -n 5
17904         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17905         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17906 }
17907 run_test 160c "verify that changelog log catch the truncate event"
17908
17909 test_160d() {
17910         remote_mds_nodsh && skip "remote MDS with nodsh"
17911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17913         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17914                 skip "Need MDS version at least 2.7.60"
17915
17916         # Registration step
17917         changelog_register || error "changelog_register failed"
17918
17919         mkdir -p $DIR/$tdir/migrate_dir
17920         changelog_clear 0 || error "changelog_clear failed"
17921
17922         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17923         changelog_dump | tail -n 5
17924         local migrates=$(changelog_dump | grep -c "MIGRT")
17925         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17926 }
17927 run_test 160d "verify that changelog log catch the migrate event"
17928
17929 test_160e() {
17930         remote_mds_nodsh && skip "remote MDS with nodsh"
17931
17932         # Create a user
17933         changelog_register || error "changelog_register failed"
17934
17935         local MDT0=$(facet_svc $SINGLEMDS)
17936         local rc
17937
17938         # No user (expect fail)
17939         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17940         rc=$?
17941         if [ $rc -eq 0 ]; then
17942                 error "Should fail without user"
17943         elif [ $rc -ne 4 ]; then
17944                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17945         fi
17946
17947         # Delete a future user (expect fail)
17948         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17949         rc=$?
17950         if [ $rc -eq 0 ]; then
17951                 error "Deleted non-existant user cl77"
17952         elif [ $rc -ne 2 ]; then
17953                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17954         fi
17955
17956         # Clear to a bad index (1 billion should be safe)
17957         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17958         rc=$?
17959
17960         if [ $rc -eq 0 ]; then
17961                 error "Successfully cleared to invalid CL index"
17962         elif [ $rc -ne 22 ]; then
17963                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17964         fi
17965 }
17966 run_test 160e "changelog negative testing (should return errors)"
17967
17968 test_160f() {
17969         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17970         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17971                 skip "Need MDS version at least 2.10.56"
17972
17973         local mdts=$(comma_list $(mdts_nodes))
17974
17975         # Create a user
17976         changelog_register || error "first changelog_register failed"
17977         changelog_register || error "second changelog_register failed"
17978         local cl_users
17979         declare -A cl_user1
17980         declare -A cl_user2
17981         local user_rec1
17982         local user_rec2
17983         local i
17984
17985         # generate some changelog records to accumulate on each MDT
17986         # use all_char because created files should be evenly distributed
17987         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17988                 error "test_mkdir $tdir failed"
17989         log "$(date +%s): creating first files"
17990         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17991                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17992                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17993         done
17994
17995         # check changelogs have been generated
17996         local start=$SECONDS
17997         local idle_time=$((MDSCOUNT * 5 + 5))
17998         local nbcl=$(changelog_dump | wc -l)
17999         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18000
18001         for param in "changelog_max_idle_time=$idle_time" \
18002                      "changelog_gc=1" \
18003                      "changelog_min_gc_interval=2" \
18004                      "changelog_min_free_cat_entries=3"; do
18005                 local MDT0=$(facet_svc $SINGLEMDS)
18006                 local var="${param%=*}"
18007                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18008
18009                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18010                 do_nodes $mdts $LCTL set_param mdd.*.$param
18011         done
18012
18013         # force cl_user2 to be idle (1st part), but also cancel the
18014         # cl_user1 records so that it is not evicted later in the test.
18015         local sleep1=$((idle_time / 2))
18016         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
18017         sleep $sleep1
18018
18019         # simulate changelog catalog almost full
18020         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
18021         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
18022
18023         for i in $(seq $MDSCOUNT); do
18024                 cl_users=(${CL_USERS[mds$i]})
18025                 cl_user1[mds$i]="${cl_users[0]}"
18026                 cl_user2[mds$i]="${cl_users[1]}"
18027
18028                 [ -n "${cl_user1[mds$i]}" ] ||
18029                         error "mds$i: no user registered"
18030                 [ -n "${cl_user2[mds$i]}" ] ||
18031                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18032
18033                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18034                 [ -n "$user_rec1" ] ||
18035                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18036                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18037                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18038                 [ -n "$user_rec2" ] ||
18039                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18040                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18041                      "$user_rec1 + 2 == $user_rec2"
18042                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18043                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18044                               "$user_rec1 + 2, but is $user_rec2"
18045                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18046                 [ -n "$user_rec2" ] ||
18047                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18048                 [ $user_rec1 == $user_rec2 ] ||
18049                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18050                               "$user_rec1, but is $user_rec2"
18051         done
18052
18053         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18054         local sleep2=$((idle_time - (SECONDS - start) + 1))
18055         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18056         sleep $sleep2
18057
18058         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18059         # cl_user1 should be OK because it recently processed records.
18060         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18061         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18062                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18063                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18064         done
18065
18066         # ensure gc thread is done
18067         for i in $(mdts_nodes); do
18068                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18069                         error "$i: GC-thread not done"
18070         done
18071
18072         local first_rec
18073         for (( i = 1; i <= MDSCOUNT; i++ )); do
18074                 # check cl_user1 still registered
18075                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18076                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18077                 # check cl_user2 unregistered
18078                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18079                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18080
18081                 # check changelogs are present and starting at $user_rec1 + 1
18082                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18083                 [ -n "$user_rec1" ] ||
18084                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18085                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18086                             awk '{ print $1; exit; }')
18087
18088                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18089                 [ $((user_rec1 + 1)) == $first_rec ] ||
18090                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18091         done
18092 }
18093 run_test 160f "changelog garbage collect (timestamped users)"
18094
18095 test_160g() {
18096         remote_mds_nodsh && skip "remote MDS with nodsh"
18097         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18098                 skip "Need MDS version at least 2.14.55"
18099
18100         local mdts=$(comma_list $(mdts_nodes))
18101
18102         # Create a user
18103         changelog_register || error "first changelog_register failed"
18104         changelog_register || error "second changelog_register failed"
18105         local cl_users
18106         declare -A cl_user1
18107         declare -A cl_user2
18108         local user_rec1
18109         local user_rec2
18110         local i
18111
18112         # generate some changelog records to accumulate on each MDT
18113         # use all_char because created files should be evenly distributed
18114         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18115                 error "test_mkdir $tdir failed"
18116         for ((i = 0; i < MDSCOUNT; i++)); do
18117                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18118                         error "create $DIR/$tdir/d$i.1 failed"
18119         done
18120
18121         # check changelogs have been generated
18122         local nbcl=$(changelog_dump | wc -l)
18123         (( $nbcl > 0 )) || error "no changelogs found"
18124
18125         # reduce the max_idle_indexes value to make sure we exceed it
18126         for param in "changelog_max_idle_indexes=2" \
18127                      "changelog_gc=1" \
18128                      "changelog_min_gc_interval=2"; do
18129                 local MDT0=$(facet_svc $SINGLEMDS)
18130                 local var="${param%=*}"
18131                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18132
18133                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18134                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18135                         error "unable to set mdd.*.$param"
18136         done
18137
18138         local start=$SECONDS
18139         for i in $(seq $MDSCOUNT); do
18140                 cl_users=(${CL_USERS[mds$i]})
18141                 cl_user1[mds$i]="${cl_users[0]}"
18142                 cl_user2[mds$i]="${cl_users[1]}"
18143
18144                 [ -n "${cl_user1[mds$i]}" ] ||
18145                         error "mds$i: user1 is not registered"
18146                 [ -n "${cl_user2[mds$i]}" ] ||
18147                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18148
18149                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18150                 [ -n "$user_rec1" ] ||
18151                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18152                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18153                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18154                 [ -n "$user_rec2" ] ||
18155                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18156                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18157                      "$user_rec1 + 2 == $user_rec2"
18158                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18159                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18160                               "expected $user_rec1 + 2, but is $user_rec2"
18161                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18162                 [ -n "$user_rec2" ] ||
18163                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18164                 [ $user_rec1 == $user_rec2 ] ||
18165                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18166                               "expected $user_rec1, but is $user_rec2"
18167         done
18168
18169         # ensure we are past the previous changelog_min_gc_interval set above
18170         local sleep2=$((start + 2 - SECONDS))
18171         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18172         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18173         # cl_user1 should be OK because it recently processed records.
18174         for ((i = 0; i < MDSCOUNT; i++)); do
18175                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18176                         error "create $DIR/$tdir/d$i.3 failed"
18177         done
18178
18179         # ensure gc thread is done
18180         for i in $(mdts_nodes); do
18181                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18182                         error "$i: GC-thread not done"
18183         done
18184
18185         local first_rec
18186         for (( i = 1; i <= MDSCOUNT; i++ )); do
18187                 # check cl_user1 still registered
18188                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18189                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18190                 # check cl_user2 unregistered
18191                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18192                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18193
18194                 # check changelogs are present and starting at $user_rec1 + 1
18195                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18196                 [ -n "$user_rec1" ] ||
18197                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18198                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18199                             awk '{ print $1; exit; }')
18200
18201                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18202                 [ $((user_rec1 + 1)) == $first_rec ] ||
18203                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18204         done
18205 }
18206 run_test 160g "changelog garbage collect on idle records"
18207
18208 test_160h() {
18209         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18210         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18211                 skip "Need MDS version at least 2.10.56"
18212
18213         local mdts=$(comma_list $(mdts_nodes))
18214
18215         # Create a user
18216         changelog_register || error "first changelog_register failed"
18217         changelog_register || error "second changelog_register failed"
18218         local cl_users
18219         declare -A cl_user1
18220         declare -A cl_user2
18221         local user_rec1
18222         local user_rec2
18223         local i
18224
18225         # generate some changelog records to accumulate on each MDT
18226         # use all_char because created files should be evenly distributed
18227         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18228                 error "test_mkdir $tdir failed"
18229         for ((i = 0; i < MDSCOUNT; i++)); do
18230                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18231                         error "create $DIR/$tdir/d$i.1 failed"
18232         done
18233
18234         # check changelogs have been generated
18235         local nbcl=$(changelog_dump | wc -l)
18236         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18237
18238         for param in "changelog_max_idle_time=10" \
18239                      "changelog_gc=1" \
18240                      "changelog_min_gc_interval=2"; do
18241                 local MDT0=$(facet_svc $SINGLEMDS)
18242                 local var="${param%=*}"
18243                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18244
18245                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18246                 do_nodes $mdts $LCTL set_param mdd.*.$param
18247         done
18248
18249         # force cl_user2 to be idle (1st part)
18250         sleep 9
18251
18252         for i in $(seq $MDSCOUNT); do
18253                 cl_users=(${CL_USERS[mds$i]})
18254                 cl_user1[mds$i]="${cl_users[0]}"
18255                 cl_user2[mds$i]="${cl_users[1]}"
18256
18257                 [ -n "${cl_user1[mds$i]}" ] ||
18258                         error "mds$i: no user registered"
18259                 [ -n "${cl_user2[mds$i]}" ] ||
18260                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18261
18262                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18263                 [ -n "$user_rec1" ] ||
18264                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18265                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18266                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18267                 [ -n "$user_rec2" ] ||
18268                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18269                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18270                      "$user_rec1 + 2 == $user_rec2"
18271                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18272                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18273                               "$user_rec1 + 2, but is $user_rec2"
18274                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18275                 [ -n "$user_rec2" ] ||
18276                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18277                 [ $user_rec1 == $user_rec2 ] ||
18278                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18279                               "$user_rec1, but is $user_rec2"
18280         done
18281
18282         # force cl_user2 to be idle (2nd part) and to reach
18283         # changelog_max_idle_time
18284         sleep 2
18285
18286         # force each GC-thread start and block then
18287         # one per MDT/MDD, set fail_val accordingly
18288         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18289         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18290
18291         # generate more changelogs to trigger fail_loc
18292         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18293                 error "create $DIR/$tdir/${tfile}bis failed"
18294
18295         # stop MDT to stop GC-thread, should be done in back-ground as it will
18296         # block waiting for the thread to be released and exit
18297         declare -A stop_pids
18298         for i in $(seq $MDSCOUNT); do
18299                 stop mds$i &
18300                 stop_pids[mds$i]=$!
18301         done
18302
18303         for i in $(mdts_nodes); do
18304                 local facet
18305                 local nb=0
18306                 local facets=$(facets_up_on_host $i)
18307
18308                 for facet in ${facets//,/ }; do
18309                         if [[ $facet == mds* ]]; then
18310                                 nb=$((nb + 1))
18311                         fi
18312                 done
18313                 # ensure each MDS's gc threads are still present and all in "R"
18314                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18315                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18316                         error "$i: expected $nb GC-thread"
18317                 wait_update $i \
18318                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18319                         "R" 20 ||
18320                         error "$i: GC-thread not found in R-state"
18321                 # check umounts of each MDT on MDS have reached kthread_stop()
18322                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18323                         error "$i: expected $nb umount"
18324                 wait_update $i \
18325                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18326                         error "$i: umount not found in D-state"
18327         done
18328
18329         # release all GC-threads
18330         do_nodes $mdts $LCTL set_param fail_loc=0
18331
18332         # wait for MDT stop to complete
18333         for i in $(seq $MDSCOUNT); do
18334                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18335         done
18336
18337         # XXX
18338         # may try to check if any orphan changelog records are present
18339         # via ldiskfs/zfs and llog_reader...
18340
18341         # re-start/mount MDTs
18342         for i in $(seq $MDSCOUNT); do
18343                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18344                         error "Fail to start mds$i"
18345         done
18346
18347         local first_rec
18348         for i in $(seq $MDSCOUNT); do
18349                 # check cl_user1 still registered
18350                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18351                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18352                 # check cl_user2 unregistered
18353                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18354                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18355
18356                 # check changelogs are present and starting at $user_rec1 + 1
18357                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18358                 [ -n "$user_rec1" ] ||
18359                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18360                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18361                             awk '{ print $1; exit; }')
18362
18363                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18364                 [ $((user_rec1 + 1)) == $first_rec ] ||
18365                         error "mds$i: first index should be $user_rec1 + 1, " \
18366                               "but is $first_rec"
18367         done
18368 }
18369 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18370               "during mount"
18371
18372 test_160i() {
18373
18374         local mdts=$(comma_list $(mdts_nodes))
18375
18376         changelog_register || error "first changelog_register failed"
18377
18378         # generate some changelog records to accumulate on each MDT
18379         # use all_char because created files should be evenly distributed
18380         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18381                 error "test_mkdir $tdir failed"
18382         for ((i = 0; i < MDSCOUNT; i++)); do
18383                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18384                         error "create $DIR/$tdir/d$i.1 failed"
18385         done
18386
18387         # check changelogs have been generated
18388         local nbcl=$(changelog_dump | wc -l)
18389         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18390
18391         # simulate race between register and unregister
18392         # XXX as fail_loc is set per-MDS, with DNE configs the race
18393         # simulation will only occur for one MDT per MDS and for the
18394         # others the normal race scenario will take place
18395         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18396         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18397         do_nodes $mdts $LCTL set_param fail_val=1
18398
18399         # unregister 1st user
18400         changelog_deregister &
18401         local pid1=$!
18402         # wait some time for deregister work to reach race rdv
18403         sleep 2
18404         # register 2nd user
18405         changelog_register || error "2nd user register failed"
18406
18407         wait $pid1 || error "1st user deregister failed"
18408
18409         local i
18410         local last_rec
18411         declare -A LAST_REC
18412         for i in $(seq $MDSCOUNT); do
18413                 if changelog_users mds$i | grep "^cl"; then
18414                         # make sure new records are added with one user present
18415                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18416                                           awk '/^current.index:/ { print $NF }')
18417                 else
18418                         error "mds$i has no user registered"
18419                 fi
18420         done
18421
18422         # generate more changelog records to accumulate on each MDT
18423         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18424                 error "create $DIR/$tdir/${tfile}bis failed"
18425
18426         for i in $(seq $MDSCOUNT); do
18427                 last_rec=$(changelog_users $SINGLEMDS |
18428                            awk '/^current.index:/ { print $NF }')
18429                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18430                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18431                         error "changelogs are off on mds$i"
18432         done
18433 }
18434 run_test 160i "changelog user register/unregister race"
18435
18436 test_160j() {
18437         remote_mds_nodsh && skip "remote MDS with nodsh"
18438         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18439                 skip "Need MDS version at least 2.12.56"
18440
18441         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18442         stack_trap "umount $MOUNT2" EXIT
18443
18444         changelog_register || error "first changelog_register failed"
18445         stack_trap "changelog_deregister" EXIT
18446
18447         # generate some changelog
18448         # use all_char because created files should be evenly distributed
18449         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18450                 error "mkdir $tdir failed"
18451         for ((i = 0; i < MDSCOUNT; i++)); do
18452                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18453                         error "create $DIR/$tdir/d$i.1 failed"
18454         done
18455
18456         # open the changelog device
18457         exec 3>/dev/changelog-$FSNAME-MDT0000
18458         stack_trap "exec 3>&-" EXIT
18459         exec 4</dev/changelog-$FSNAME-MDT0000
18460         stack_trap "exec 4<&-" EXIT
18461
18462         # umount the first lustre mount
18463         umount $MOUNT
18464         stack_trap "mount_client $MOUNT" EXIT
18465
18466         # read changelog, which may or may not fail, but should not crash
18467         cat <&4 >/dev/null
18468
18469         # clear changelog
18470         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18471         changelog_users $SINGLEMDS | grep -q $cl_user ||
18472                 error "User $cl_user not found in changelog_users"
18473
18474         printf 'clear:'$cl_user':0' >&3
18475 }
18476 run_test 160j "client can be umounted while its chanangelog is being used"
18477
18478 test_160k() {
18479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18480         remote_mds_nodsh && skip "remote MDS with nodsh"
18481
18482         mkdir -p $DIR/$tdir/1/1
18483
18484         changelog_register || error "changelog_register failed"
18485         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18486
18487         changelog_users $SINGLEMDS | grep -q $cl_user ||
18488                 error "User '$cl_user' not found in changelog_users"
18489 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18490         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18491         rmdir $DIR/$tdir/1/1 & sleep 1
18492         mkdir $DIR/$tdir/2
18493         touch $DIR/$tdir/2/2
18494         rm -rf $DIR/$tdir/2
18495
18496         wait
18497         sleep 4
18498
18499         changelog_dump | grep rmdir || error "rmdir not recorded"
18500 }
18501 run_test 160k "Verify that changelog records are not lost"
18502
18503 # Verifies that a file passed as a parameter has recently had an operation
18504 # performed on it that has generated an MTIME changelog which contains the
18505 # correct parent FID. As files might reside on a different MDT from the
18506 # parent directory in DNE configurations, the FIDs are translated to paths
18507 # before being compared, which should be identical
18508 compare_mtime_changelog() {
18509         local file="${1}"
18510         local mdtidx
18511         local mtime
18512         local cl_fid
18513         local pdir
18514         local dir
18515
18516         mdtidx=$($LFS getstripe --mdt-index $file)
18517         mdtidx=$(printf "%04x" $mdtidx)
18518
18519         # Obtain the parent FID from the MTIME changelog
18520         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18521         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18522
18523         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18524         [ -z "$cl_fid" ] && error "parent FID not present"
18525
18526         # Verify that the path for the parent FID is the same as the path for
18527         # the test directory
18528         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18529
18530         dir=$(dirname $1)
18531
18532         [[ "${pdir%/}" == "$dir" ]] ||
18533                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18534 }
18535
18536 test_160l() {
18537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18538
18539         remote_mds_nodsh && skip "remote MDS with nodsh"
18540         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18541                 skip "Need MDS version at least 2.13.55"
18542
18543         local cl_user
18544
18545         changelog_register || error "changelog_register failed"
18546         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18547
18548         changelog_users $SINGLEMDS | grep -q $cl_user ||
18549                 error "User '$cl_user' not found in changelog_users"
18550
18551         # Clear some types so that MTIME changelogs are generated
18552         changelog_chmask "-CREAT"
18553         changelog_chmask "-CLOSE"
18554
18555         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18556
18557         # Test CL_MTIME during setattr
18558         touch $DIR/$tdir/$tfile
18559         compare_mtime_changelog $DIR/$tdir/$tfile
18560
18561         # Test CL_MTIME during close
18562         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18563         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18564 }
18565 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18566
18567 test_160m() {
18568         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18569         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18570                 skip "Need MDS version at least 2.14.51"
18571         local cl_users
18572         local cl_user1
18573         local cl_user2
18574         local pid1
18575
18576         # Create a user
18577         changelog_register || error "first changelog_register failed"
18578         changelog_register || error "second changelog_register failed"
18579
18580         cl_users=(${CL_USERS[mds1]})
18581         cl_user1="${cl_users[0]}"
18582         cl_user2="${cl_users[1]}"
18583         # generate some changelog records to accumulate on MDT0
18584         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18585         createmany -m $DIR/$tdir/$tfile 50 ||
18586                 error "create $DIR/$tdir/$tfile failed"
18587         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18588         rm -f $DIR/$tdir
18589
18590         # check changelogs have been generated
18591         local nbcl=$(changelog_dump | wc -l)
18592         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18593
18594 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18595         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18596
18597         __changelog_clear mds1 $cl_user1 +10
18598         __changelog_clear mds1 $cl_user2 0 &
18599         pid1=$!
18600         sleep 2
18601         __changelog_clear mds1 $cl_user1 0 ||
18602                 error "fail to cancel record for $cl_user1"
18603         wait $pid1
18604         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18605 }
18606 run_test 160m "Changelog clear race"
18607
18608 test_160n() {
18609         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18610         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18611                 skip "Need MDS version at least 2.14.51"
18612         local cl_users
18613         local cl_user1
18614         local cl_user2
18615         local pid1
18616         local first_rec
18617         local last_rec=0
18618
18619         # Create a user
18620         changelog_register || error "first changelog_register failed"
18621
18622         cl_users=(${CL_USERS[mds1]})
18623         cl_user1="${cl_users[0]}"
18624
18625         # generate some changelog records to accumulate on MDT0
18626         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18627         first_rec=$(changelog_users $SINGLEMDS |
18628                         awk '/^current.index:/ { print $NF }')
18629         while (( last_rec < (( first_rec + 65000)) )); do
18630                 createmany -m $DIR/$tdir/$tfile 10000 ||
18631                         error "create $DIR/$tdir/$tfile failed"
18632
18633                 for i in $(seq 0 10000); do
18634                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18635                                 > /dev/null
18636                 done
18637
18638                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18639                         error "unlinkmany failed unlink"
18640                 last_rec=$(changelog_users $SINGLEMDS |
18641                         awk '/^current.index:/ { print $NF }')
18642                 echo last record $last_rec
18643                 (( last_rec == 0 )) && error "no changelog found"
18644         done
18645
18646 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18647         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18648
18649         __changelog_clear mds1 $cl_user1 0 &
18650         pid1=$!
18651         sleep 2
18652         __changelog_clear mds1 $cl_user1 0 ||
18653                 error "fail to cancel record for $cl_user1"
18654         wait $pid1
18655         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18656 }
18657 run_test 160n "Changelog destroy race"
18658
18659 test_160o() {
18660         local mdt="$(facet_svc $SINGLEMDS)"
18661
18662         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18663         remote_mds_nodsh && skip "remote MDS with nodsh"
18664         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18665                 skip "Need MDS version at least 2.14.52"
18666
18667         changelog_register --user test_160o -m unlnk+close+open ||
18668                 error "changelog_register failed"
18669
18670         do_facet $SINGLEMDS $LCTL --device $mdt \
18671                                 changelog_register -u "Tt3_-#" &&
18672                 error "bad symbols in name should fail"
18673
18674         do_facet $SINGLEMDS $LCTL --device $mdt \
18675                                 changelog_register -u test_160o &&
18676                 error "the same name registration should fail"
18677
18678         do_facet $SINGLEMDS $LCTL --device $mdt \
18679                         changelog_register -u test_160toolongname &&
18680                 error "too long name registration should fail"
18681
18682         changelog_chmask "MARK+HSM"
18683         lctl get_param mdd.*.changelog*mask
18684         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18685         changelog_users $SINGLEMDS | grep -q $cl_user ||
18686                 error "User $cl_user not found in changelog_users"
18687         #verify username
18688         echo $cl_user | grep -q test_160o ||
18689                 error "User $cl_user has no specific name 'test160o'"
18690
18691         # change something
18692         changelog_clear 0 || error "changelog_clear failed"
18693         # generate some changelog records to accumulate on MDT0
18694         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18695         touch $DIR/$tdir/$tfile                 # open 1
18696
18697         OPENS=$(changelog_dump | grep -c "OPEN")
18698         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18699
18700         # must be no MKDIR it wasn't set as user mask
18701         MKDIR=$(changelog_dump | grep -c "MKDIR")
18702         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18703
18704         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18705                                 mdd.$mdt.changelog_current_mask -n)
18706         # register maskless user
18707         changelog_register || error "changelog_register failed"
18708         # effective mask should be not changed because it is not minimal
18709         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18710                                 mdd.$mdt.changelog_current_mask -n)
18711         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18712         # set server mask to minimal value
18713         changelog_chmask "MARK"
18714         # check effective mask again, should be treated as DEFMASK now
18715         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18716                                 mdd.$mdt.changelog_current_mask -n)
18717         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18718
18719         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18720                 # set server mask back to some value
18721                 changelog_chmask "CLOSE,UNLNK"
18722                 # check effective mask again, should not remain as DEFMASK
18723                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18724                                 mdd.$mdt.changelog_current_mask -n)
18725                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18726         fi
18727
18728         do_facet $SINGLEMDS $LCTL --device $mdt \
18729                                 changelog_deregister -u test_160o ||
18730                 error "cannot deregister by name"
18731 }
18732 run_test 160o "changelog user name and mask"
18733
18734 test_160p() {
18735         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18736         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18737                 skip "Need MDS version at least 2.14.51"
18738         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18739         local cl_users
18740         local cl_user1
18741         local entry_count
18742
18743         # Create a user
18744         changelog_register || error "first changelog_register failed"
18745
18746         cl_users=(${CL_USERS[mds1]})
18747         cl_user1="${cl_users[0]}"
18748
18749         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18750         createmany -m $DIR/$tdir/$tfile 50 ||
18751                 error "create $DIR/$tdir/$tfile failed"
18752         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18753         rm -rf $DIR/$tdir
18754
18755         # check changelogs have been generated
18756         entry_count=$(changelog_dump | wc -l)
18757         ((entry_count != 0)) || error "no changelog entries found"
18758
18759         # remove changelog_users and check that orphan entries are removed
18760         stop mds1
18761         local dev=$(mdsdevname 1)
18762         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18763         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18764         entry_count=$(changelog_dump | wc -l)
18765         ((entry_count == 0)) ||
18766                 error "found $entry_count changelog entries, expected none"
18767 }
18768 run_test 160p "Changelog orphan cleanup with no users"
18769
18770 test_160q() {
18771         local mdt="$(facet_svc $SINGLEMDS)"
18772         local clu
18773
18774         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18775         remote_mds_nodsh && skip "remote MDS with nodsh"
18776         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18777                 skip "Need MDS version at least 2.14.54"
18778
18779         # set server mask to minimal value like server init does
18780         changelog_chmask "MARK"
18781         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18782                 error "changelog_register failed"
18783         # check effective mask again, should be treated as DEFMASK now
18784         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18785                                 mdd.$mdt.changelog_current_mask -n)
18786         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18787                 error "changelog_deregister failed"
18788         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18789 }
18790 run_test 160q "changelog effective mask is DEFMASK if not set"
18791
18792 test_160s() {
18793         remote_mds_nodsh && skip "remote MDS with nodsh"
18794         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18795                 skip "Need MDS version at least 2.14.55"
18796
18797         local mdts=$(comma_list $(mdts_nodes))
18798
18799         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18800         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18801                                        fail_val=$((24 * 3600 * 10))
18802
18803         # Create a user which is 10 days old
18804         changelog_register || error "first changelog_register failed"
18805         local cl_users
18806         declare -A cl_user1
18807         local i
18808
18809         # generate some changelog records to accumulate on each MDT
18810         # use all_char because created files should be evenly distributed
18811         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18812                 error "test_mkdir $tdir failed"
18813         for ((i = 0; i < MDSCOUNT; i++)); do
18814                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18815                         error "create $DIR/$tdir/d$i.1 failed"
18816         done
18817
18818         # check changelogs have been generated
18819         local nbcl=$(changelog_dump | wc -l)
18820         (( nbcl > 0 )) || error "no changelogs found"
18821
18822         # reduce the max_idle_indexes value to make sure we exceed it
18823         for param in "changelog_max_idle_indexes=2097446912" \
18824                      "changelog_max_idle_time=2592000" \
18825                      "changelog_gc=1" \
18826                      "changelog_min_gc_interval=2"; do
18827                 local MDT0=$(facet_svc $SINGLEMDS)
18828                 local var="${param%=*}"
18829                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18830
18831                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18832                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18833                         error "unable to set mdd.*.$param"
18834         done
18835
18836         local start=$SECONDS
18837         for i in $(seq $MDSCOUNT); do
18838                 cl_users=(${CL_USERS[mds$i]})
18839                 cl_user1[mds$i]="${cl_users[0]}"
18840
18841                 [[ -n "${cl_user1[mds$i]}" ]] ||
18842                         error "mds$i: no user registered"
18843         done
18844
18845         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18846         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18847
18848         # ensure we are past the previous changelog_min_gc_interval set above
18849         local sleep2=$((start + 2 - SECONDS))
18850         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18851
18852         # Generate one more changelog to trigger GC
18853         for ((i = 0; i < MDSCOUNT; i++)); do
18854                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18855                         error "create $DIR/$tdir/d$i.3 failed"
18856         done
18857
18858         # ensure gc thread is done
18859         for node in $(mdts_nodes); do
18860                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18861                         error "$node: GC-thread not done"
18862         done
18863
18864         do_nodes $mdts $LCTL set_param fail_loc=0
18865
18866         for (( i = 1; i <= MDSCOUNT; i++ )); do
18867                 # check cl_user1 is purged
18868                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18869                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18870         done
18871         return 0
18872 }
18873 run_test 160s "changelog garbage collect on idle records * time"
18874
18875 test_160t() {
18876         remote_mds_nodsh && skip "remote MDS with nodsh"
18877         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18878                 skip "Need MDS version at least 2.15.50"
18879
18880         local MDT0=$(facet_svc $SINGLEMDS)
18881         local cl_users
18882         local cl_user1
18883         local cl_user2
18884         local start
18885
18886         changelog_register --user user1 -m all ||
18887                 error "user1 failed to register"
18888
18889         mkdir_on_mdt0 $DIR/$tdir
18890         # create default overstripe to maximize changelog size
18891         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18892         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18893         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18894
18895         # user2 consumes less records so less space
18896         changelog_register --user user2 || error "user2 failed to register"
18897         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18898         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18899
18900         # check changelogs have been generated
18901         local nbcl=$(changelog_dump | wc -l)
18902         (( nbcl > 0 )) || error "no changelogs found"
18903
18904         # reduce the changelog_min_gc_interval to force check
18905         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18906                 local var="${param%=*}"
18907                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18908
18909                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18910                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18911                         error "unable to set mdd.*.$param"
18912         done
18913
18914         start=$SECONDS
18915         cl_users=(${CL_USERS[mds1]})
18916         cl_user1="${cl_users[0]}"
18917         cl_user2="${cl_users[1]}"
18918
18919         [[ -n $cl_user1 ]] ||
18920                 error "mds1: user #1 isn't registered"
18921         [[ -n $cl_user2 ]] ||
18922                 error "mds1: user #2 isn't registered"
18923
18924         # ensure we are past the previous changelog_min_gc_interval set above
18925         local sleep2=$((start + 2 - SECONDS))
18926         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18927
18928         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18929         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18930                         fail_val=$(((llog_size1 + llog_size2) / 2))
18931
18932         # Generate more changelog to trigger GC
18933         createmany -o $DIR/$tdir/u3_ 4 ||
18934                 error "create failed for more files"
18935
18936         # ensure gc thread is done
18937         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18938                 error "mds1: GC-thread not done"
18939
18940         do_facet mds1 $LCTL set_param fail_loc=0
18941
18942         # check cl_user1 is purged
18943         changelog_users mds1 | grep -q "$cl_user1" &&
18944                 error "User $cl_user1 is registered"
18945         # check cl_user2 is not purged
18946         changelog_users mds1 | grep -q "$cl_user2" ||
18947                 error "User $cl_user2 is not registered"
18948 }
18949 run_test 160t "changelog garbage collect on lack of space"
18950
18951 test_160u() { # LU-17400
18952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18953         remote_mds_nodsh && skip "remote MDS with nodsh"
18954         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18955                 skip "Need MDS version at least 2.2.0"
18956
18957         cd $DIR || error "cd $DIR failed"
18958
18959         # ensure changelog has a clean view if tests are run multiple times
18960         [ -d rename ] && rm -rf rename
18961
18962         changelog_register || error "changelog_register failed"
18963         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18964
18965         changelog_users $SINGLEMDS | grep -q $cl_user ||
18966                 error "User '$cl_user' not found in changelog_users"
18967
18968         local longname1=$(str_repeat a 255)
18969
18970         echo "creating simple directory tree"
18971         mkdir -p rename/a || error "create of simple directory tree failed"
18972         echo "creating rename/hw file"
18973         echo "hello world" > rename/hw || error "create of rename/hw failed"
18974         echo "creating very long named file"
18975         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18976         echo "move rename/hw to rename/a/a.hw"
18977         mv rename/hw rename/a/a.hw || error "mv failed"
18978
18979         RENME=($(changelog_dump | grep "RENME"))
18980         #declare -p RENME # for debugging captured value with indexes
18981
18982         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18983                 error "changelog rename record type name/sname error"
18984 }
18985 run_test 160u "changelog rename record type name and sname strings are correct"
18986
18987 test_161a() {
18988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18989
18990         test_mkdir -c1 $DIR/$tdir
18991         cp /etc/hosts $DIR/$tdir/$tfile
18992         test_mkdir -c1 $DIR/$tdir/foo1
18993         test_mkdir -c1 $DIR/$tdir/foo2
18994         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18995         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18996         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18997         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18998         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18999         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19000                 $LFS fid2path $DIR $FID
19001                 error "bad link ea"
19002         fi
19003         # middle
19004         rm $DIR/$tdir/foo2/zachary
19005         # last
19006         rm $DIR/$tdir/foo2/thor
19007         # first
19008         rm $DIR/$tdir/$tfile
19009         # rename
19010         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
19011         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
19012                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
19013         rm $DIR/$tdir/foo2/maggie
19014
19015         # overflow the EA
19016         local longname=$tfile.avg_len_is_thirty_two_
19017         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
19018                 error_noexit 'failed to unlink many hardlinks'" EXIT
19019         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
19020                 error "failed to hardlink many files"
19021         links=$($LFS fid2path $DIR $FID | wc -l)
19022         echo -n "${links}/1000 links in link EA"
19023         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
19024 }
19025 run_test 161a "link ea sanity"
19026
19027 test_161b() {
19028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19029         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
19030
19031         local MDTIDX=1
19032         local remote_dir=$DIR/$tdir/remote_dir
19033
19034         mkdir -p $DIR/$tdir
19035         $LFS mkdir -i $MDTIDX $remote_dir ||
19036                 error "create remote directory failed"
19037
19038         cp /etc/hosts $remote_dir/$tfile
19039         mkdir -p $remote_dir/foo1
19040         mkdir -p $remote_dir/foo2
19041         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19042         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19043         ln $remote_dir/$tfile $remote_dir/foo1/luna
19044         ln $remote_dir/$tfile $remote_dir/foo2/thor
19045
19046         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19047                      tr -d ']')
19048         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19049                 $LFS fid2path $DIR $FID
19050                 error "bad link ea"
19051         fi
19052         # middle
19053         rm $remote_dir/foo2/zachary
19054         # last
19055         rm $remote_dir/foo2/thor
19056         # first
19057         rm $remote_dir/$tfile
19058         # rename
19059         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19060         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19061         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19062                 $LFS fid2path $DIR $FID
19063                 error "bad link rename"
19064         fi
19065         rm $remote_dir/foo2/maggie
19066
19067         # overflow the EA
19068         local longname=filename_avg_len_is_thirty_two_
19069         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19070                 error "failed to hardlink many files"
19071         links=$($LFS fid2path $DIR $FID | wc -l)
19072         echo -n "${links}/1000 links in link EA"
19073         [[ ${links} -gt 60 ]] ||
19074                 error "expected at least 60 links in link EA"
19075         unlinkmany $remote_dir/foo2/$longname 1000 ||
19076         error "failed to unlink many hardlinks"
19077 }
19078 run_test 161b "link ea sanity under remote directory"
19079
19080 test_161c() {
19081         remote_mds_nodsh && skip "remote MDS with nodsh"
19082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19083         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19084                 skip "Need MDS version at least 2.1.5"
19085
19086         # define CLF_RENAME_LAST 0x0001
19087         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19088         changelog_register || error "changelog_register failed"
19089
19090         rm -rf $DIR/$tdir
19091         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19092         touch $DIR/$tdir/foo_161c
19093         touch $DIR/$tdir/bar_161c
19094         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19095         changelog_dump | grep RENME | tail -n 5
19096         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19097         changelog_clear 0 || error "changelog_clear failed"
19098         if [ x$flags != "x0x1" ]; then
19099                 error "flag $flags is not 0x1"
19100         fi
19101
19102         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19103         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19104         touch $DIR/$tdir/foo_161c
19105         touch $DIR/$tdir/bar_161c
19106         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19107         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19108         changelog_dump | grep RENME | tail -n 5
19109         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19110         changelog_clear 0 || error "changelog_clear failed"
19111         if [ x$flags != "x0x0" ]; then
19112                 error "flag $flags is not 0x0"
19113         fi
19114         echo "rename overwrite a target having nlink > 1," \
19115                 "changelog record has flags of $flags"
19116
19117         # rename doesn't overwrite a target (changelog flag 0x0)
19118         touch $DIR/$tdir/foo_161c
19119         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19120         changelog_dump | grep RENME | tail -n 5
19121         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19122         changelog_clear 0 || error "changelog_clear failed"
19123         if [ x$flags != "x0x0" ]; then
19124                 error "flag $flags is not 0x0"
19125         fi
19126         echo "rename doesn't overwrite a target," \
19127                 "changelog record has flags of $flags"
19128
19129         # define CLF_UNLINK_LAST 0x0001
19130         # unlink a file having nlink = 1 (changelog flag 0x1)
19131         rm -f $DIR/$tdir/foo2_161c
19132         changelog_dump | grep UNLNK | tail -n 5
19133         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19134         changelog_clear 0 || error "changelog_clear failed"
19135         if [ x$flags != "x0x1" ]; then
19136                 error "flag $flags is not 0x1"
19137         fi
19138         echo "unlink a file having nlink = 1," \
19139                 "changelog record has flags of $flags"
19140
19141         # unlink a file having nlink > 1 (changelog flag 0x0)
19142         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19143         rm -f $DIR/$tdir/foobar_161c
19144         changelog_dump | grep UNLNK | tail -n 5
19145         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19146         changelog_clear 0 || error "changelog_clear failed"
19147         if [ x$flags != "x0x0" ]; then
19148                 error "flag $flags is not 0x0"
19149         fi
19150         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19151 }
19152 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19153
19154 test_161d() {
19155         remote_mds_nodsh && skip "remote MDS with nodsh"
19156         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19157
19158         local pid
19159         local fid
19160
19161         changelog_register || error "changelog_register failed"
19162
19163         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19164         # interfer with $MOUNT/.lustre/fid/ access
19165         mkdir $DIR/$tdir
19166         [[ $? -eq 0 ]] || error "mkdir failed"
19167
19168         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19169         $LCTL set_param fail_loc=0x8000140c
19170         # 5s pause
19171         $LCTL set_param fail_val=5
19172
19173         # create file
19174         echo foofoo > $DIR/$tdir/$tfile &
19175         pid=$!
19176
19177         # wait for create to be delayed
19178         sleep 2
19179
19180         ps -p $pid
19181         [[ $? -eq 0 ]] || error "create should be blocked"
19182
19183         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19184         stack_trap "rm -f $tempfile"
19185         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19186         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19187         # some delay may occur during ChangeLog publishing and file read just
19188         # above, that could allow file write to happen finally
19189         [[ -s $tempfile ]] && echo "file should be empty"
19190
19191         $LCTL set_param fail_loc=0
19192
19193         wait $pid
19194         [[ $? -eq 0 ]] || error "create failed"
19195 }
19196 run_test 161d "create with concurrent .lustre/fid access"
19197
19198 check_path() {
19199         local expected="$1"
19200         shift
19201         local fid="$2"
19202
19203         local path
19204         path=$($LFS fid2path "$@")
19205         local rc=$?
19206
19207         if [ $rc -ne 0 ]; then
19208                 error "path looked up of '$expected' failed: rc=$rc"
19209         elif [ "$path" != "$expected" ]; then
19210                 error "path looked up '$path' instead of '$expected'"
19211         else
19212                 echo "FID '$fid' resolves to path '$path' as expected"
19213         fi
19214 }
19215
19216 test_162a() { # was test_162
19217         test_mkdir -p -c1 $DIR/$tdir/d2
19218         touch $DIR/$tdir/d2/$tfile
19219         touch $DIR/$tdir/d2/x1
19220         touch $DIR/$tdir/d2/x2
19221         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19222         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19223         # regular file
19224         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19225         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19226
19227         # softlink
19228         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19229         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19230         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19231
19232         # softlink to wrong file
19233         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19234         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19235         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19236
19237         # hardlink
19238         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19239         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19240         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19241         # fid2path dir/fsname should both work
19242         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19243         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19244
19245         # hardlink count: check that there are 2 links
19246         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19247         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19248
19249         # hardlink indexing: remove the first link
19250         rm $DIR/$tdir/d2/p/q/r/hlink
19251         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19252 }
19253 run_test 162a "path lookup sanity"
19254
19255 test_162b() {
19256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19258
19259         mkdir $DIR/$tdir
19260         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19261                                 error "create striped dir failed"
19262
19263         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19264                                         tail -n 1 | awk '{print $2}')
19265         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19266
19267         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19268         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19269
19270         # regular file
19271         for ((i=0;i<5;i++)); do
19272                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19273                         error "get fid for f$i failed"
19274                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19275
19276                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19277                         error "get fid for d$i failed"
19278                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19279         done
19280
19281         return 0
19282 }
19283 run_test 162b "striped directory path lookup sanity"
19284
19285 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19286 test_162c() {
19287         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19288                 skip "Need MDS version at least 2.7.51"
19289
19290         local lpath=$tdir.local
19291         local rpath=$tdir.remote
19292
19293         test_mkdir $DIR/$lpath
19294         test_mkdir $DIR/$rpath
19295
19296         for ((i = 0; i <= 101; i++)); do
19297                 lpath="$lpath/$i"
19298                 mkdir $DIR/$lpath
19299                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19300                         error "get fid for local directory $DIR/$lpath failed"
19301                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19302
19303                 rpath="$rpath/$i"
19304                 test_mkdir $DIR/$rpath
19305                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19306                         error "get fid for remote directory $DIR/$rpath failed"
19307                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19308         done
19309
19310         return 0
19311 }
19312 run_test 162c "fid2path works with paths 100 or more directories deep"
19313
19314 oalr_event_count() {
19315         local event="${1}"
19316         local trace="${2}"
19317
19318         awk -v name="${FSNAME}-OST0000" \
19319             -v event="${event}" \
19320             '$1 == "TRACE" && $2 == event && $3 == name' \
19321             "${trace}" |
19322         wc -l
19323 }
19324
19325 oalr_expect_event_count() {
19326         local event="${1}"
19327         local trace="${2}"
19328         local expect="${3}"
19329         local count
19330
19331         count=$(oalr_event_count "${event}" "${trace}")
19332         if ((count == expect)); then
19333                 return 0
19334         fi
19335
19336         error_noexit "${event} event count was '${count}', expected ${expect}"
19337         cat "${trace}" >&2
19338         exit 1
19339 }
19340
19341 cleanup_165() {
19342         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19343         stop ost1
19344         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19345 }
19346
19347 setup_165() {
19348         sync # Flush previous IOs so we can count log entries.
19349         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19350         stack_trap cleanup_165 EXIT
19351 }
19352
19353 test_165a() {
19354         local trace="/tmp/${tfile}.trace"
19355         local rc
19356         local count
19357
19358         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19359                 skip "OFD access log unsupported"
19360
19361         setup_165
19362         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19363         sleep 5
19364
19365         do_facet ost1 ofd_access_log_reader --list
19366         stop ost1
19367
19368         do_facet ost1 killall -TERM ofd_access_log_reader
19369         wait
19370         rc=$?
19371
19372         if ((rc != 0)); then
19373                 error "ofd_access_log_reader exited with rc = '${rc}'"
19374         fi
19375
19376         # Parse trace file for discovery events:
19377         oalr_expect_event_count alr_log_add "${trace}" 1
19378         oalr_expect_event_count alr_log_eof "${trace}" 1
19379         oalr_expect_event_count alr_log_free "${trace}" 1
19380 }
19381 run_test 165a "ofd access log discovery"
19382
19383 test_165b() {
19384         local trace="/tmp/${tfile}.trace"
19385         local file="${DIR}/${tfile}"
19386         local pfid1
19387         local pfid2
19388         local -a entry
19389         local rc
19390         local count
19391         local size
19392         local flags
19393
19394         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19395                 skip "OFD access log unsupported"
19396
19397         setup_165
19398         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19399         sleep 5
19400
19401         do_facet ost1 ofd_access_log_reader --list
19402
19403         lfs setstripe -c 1 -i 0 "${file}"
19404         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19405                 error "cannot create '${file}'"
19406
19407         sleep 5
19408         do_facet ost1 killall -TERM ofd_access_log_reader
19409         wait
19410         rc=$?
19411
19412         if ((rc != 0)); then
19413                 error "ofd_access_log_reader exited with rc = '${rc}'"
19414         fi
19415
19416         oalr_expect_event_count alr_log_entry "${trace}" 1
19417
19418         pfid1=$($LFS path2fid "${file}")
19419
19420         # 1     2             3   4    5     6   7    8    9     10
19421         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19422         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19423
19424         echo "entry = '${entry[*]}'" >&2
19425
19426         pfid2=${entry[4]}
19427         if [[ "${pfid1}" != "${pfid2}" ]]; then
19428                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19429         fi
19430
19431         size=${entry[8]}
19432         if ((size != 1048576)); then
19433                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19434         fi
19435
19436         flags=${entry[10]}
19437         if [[ "${flags}" != "w" ]]; then
19438                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19439         fi
19440
19441         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19442         sleep 5
19443
19444         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19445                 error "cannot read '${file}'"
19446         sleep 5
19447
19448         do_facet ost1 killall -TERM ofd_access_log_reader
19449         wait
19450         rc=$?
19451
19452         if ((rc != 0)); then
19453                 error "ofd_access_log_reader exited with rc = '${rc}'"
19454         fi
19455
19456         oalr_expect_event_count alr_log_entry "${trace}" 1
19457
19458         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19459         echo "entry = '${entry[*]}'" >&2
19460
19461         pfid2=${entry[4]}
19462         if [[ "${pfid1}" != "${pfid2}" ]]; then
19463                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19464         fi
19465
19466         size=${entry[8]}
19467         if ((size != 524288)); then
19468                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19469         fi
19470
19471         flags=${entry[10]}
19472         if [[ "${flags}" != "r" ]]; then
19473                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19474         fi
19475 }
19476 run_test 165b "ofd access log entries are produced and consumed"
19477
19478 test_165c() {
19479         local trace="/tmp/${tfile}.trace"
19480         local file="${DIR}/${tdir}/${tfile}"
19481
19482         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19483                 skip "OFD access log unsupported"
19484
19485         test_mkdir "${DIR}/${tdir}"
19486
19487         setup_165
19488         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19489         sleep 5
19490
19491         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19492
19493         # 4096 / 64 = 64. Create twice as many entries.
19494         for ((i = 0; i < 128; i++)); do
19495                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19496                         error "cannot create file"
19497         done
19498
19499         sync
19500
19501         do_facet ost1 killall -TERM ofd_access_log_reader
19502         wait
19503         rc=$?
19504         if ((rc != 0)); then
19505                 error "ofd_access_log_reader exited with rc = '${rc}'"
19506         fi
19507
19508         unlinkmany  "${file}-%d" 128
19509 }
19510 run_test 165c "full ofd access logs do not block IOs"
19511
19512 oal_get_read_count() {
19513         local stats="$1"
19514
19515         # STATS lustre-OST0001 alr_read_count 1
19516
19517         do_facet ost1 cat "${stats}" |
19518         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19519              END { print count; }'
19520 }
19521
19522 oal_expect_read_count() {
19523         local stats="$1"
19524         local count
19525         local expect="$2"
19526
19527         # Ask ofd_access_log_reader to write stats.
19528         do_facet ost1 killall -USR1 ofd_access_log_reader
19529
19530         # Allow some time for things to happen.
19531         sleep 1
19532
19533         count=$(oal_get_read_count "${stats}")
19534         if ((count == expect)); then
19535                 return 0
19536         fi
19537
19538         error_noexit "bad read count, got ${count}, expected ${expect}"
19539         do_facet ost1 cat "${stats}" >&2
19540         exit 1
19541 }
19542
19543 test_165d() {
19544         local stats="/tmp/${tfile}.stats"
19545         local file="${DIR}/${tdir}/${tfile}"
19546         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19547
19548         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19549                 skip "OFD access log unsupported"
19550
19551         test_mkdir "${DIR}/${tdir}"
19552
19553         setup_165
19554         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19555         sleep 5
19556
19557         lfs setstripe -c 1 -i 0 "${file}"
19558
19559         do_facet ost1 lctl set_param "${param}=rw"
19560         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19561                 error "cannot create '${file}'"
19562         oal_expect_read_count "${stats}" 1
19563
19564         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19565                 error "cannot read '${file}'"
19566         oal_expect_read_count "${stats}" 2
19567
19568         do_facet ost1 lctl set_param "${param}=r"
19569         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19570                 error "cannot create '${file}'"
19571         oal_expect_read_count "${stats}" 2
19572
19573         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19574                 error "cannot read '${file}'"
19575         oal_expect_read_count "${stats}" 3
19576
19577         do_facet ost1 lctl set_param "${param}=w"
19578         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19579                 error "cannot create '${file}'"
19580         oal_expect_read_count "${stats}" 4
19581
19582         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19583                 error "cannot read '${file}'"
19584         oal_expect_read_count "${stats}" 4
19585
19586         do_facet ost1 lctl set_param "${param}=0"
19587         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19588                 error "cannot create '${file}'"
19589         oal_expect_read_count "${stats}" 4
19590
19591         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19592                 error "cannot read '${file}'"
19593         oal_expect_read_count "${stats}" 4
19594
19595         do_facet ost1 killall -TERM ofd_access_log_reader
19596         wait
19597         rc=$?
19598         if ((rc != 0)); then
19599                 error "ofd_access_log_reader exited with rc = '${rc}'"
19600         fi
19601 }
19602 run_test 165d "ofd_access_log mask works"
19603
19604 test_165e() {
19605         local stats="/tmp/${tfile}.stats"
19606         local file0="${DIR}/${tdir}-0/${tfile}"
19607         local file1="${DIR}/${tdir}-1/${tfile}"
19608
19609         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19610                 skip "OFD access log unsupported"
19611
19612         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19613
19614         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19615         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19616
19617         lfs setstripe -c 1 -i 0 "${file0}"
19618         lfs setstripe -c 1 -i 0 "${file1}"
19619
19620         setup_165
19621         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19622         sleep 5
19623
19624         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19625                 error "cannot create '${file0}'"
19626         sync
19627         oal_expect_read_count "${stats}" 0
19628
19629         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19630                 error "cannot create '${file1}'"
19631         sync
19632         oal_expect_read_count "${stats}" 1
19633
19634         do_facet ost1 killall -TERM ofd_access_log_reader
19635         wait
19636         rc=$?
19637         if ((rc != 0)); then
19638                 error "ofd_access_log_reader exited with rc = '${rc}'"
19639         fi
19640 }
19641 run_test 165e "ofd_access_log MDT index filter works"
19642
19643 test_165f() {
19644         local trace="/tmp/${tfile}.trace"
19645         local rc
19646         local count
19647
19648         setup_165
19649         do_facet ost1 timeout 60 ofd_access_log_reader \
19650                 --exit-on-close --debug=- --trace=- > "${trace}" &
19651         sleep 5
19652         stop ost1
19653
19654         wait
19655         rc=$?
19656
19657         if ((rc != 0)); then
19658                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19659                 cat "${trace}"
19660                 exit 1
19661         fi
19662 }
19663 run_test 165f "ofd_access_log_reader --exit-on-close works"
19664
19665 test_169() {
19666         # do directio so as not to populate the page cache
19667         log "creating a 10 Mb file"
19668         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19669                 error "multiop failed while creating a file"
19670         log "starting reads"
19671         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19672         log "truncating the file"
19673         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19674                 error "multiop failed while truncating the file"
19675         log "killing dd"
19676         kill %+ || true # reads might have finished
19677         echo "wait until dd is finished"
19678         wait
19679         log "removing the temporary file"
19680         rm -rf $DIR/$tfile || error "tmp file removal failed"
19681 }
19682 run_test 169 "parallel read and truncate should not deadlock"
19683
19684 test_170() {
19685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19686
19687         $LCTL clear     # bug 18514
19688         $LCTL debug_daemon start $TMP/${tfile}_log_good
19689         touch $DIR/$tfile
19690         $LCTL debug_daemon stop
19691         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19692                 error "sed failed to read log_good"
19693
19694         $LCTL debug_daemon start $TMP/${tfile}_log_good
19695         rm -rf $DIR/$tfile
19696         $LCTL debug_daemon stop
19697
19698         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19699                error "lctl df log_bad failed"
19700
19701         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19702         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19703
19704         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19705         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19706
19707         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19708                 error "bad_line good_line1 good_line2 are empty"
19709
19710         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19711         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19712         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19713
19714         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19715         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19716         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19717
19718         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19719                 error "bad_line_new good_line_new are empty"
19720
19721         local expected_good=$((good_line1 + good_line2*2))
19722
19723         rm -f $TMP/${tfile}*
19724         # LU-231, short malformed line may not be counted into bad lines
19725         if [ $bad_line -ne $bad_line_new ] &&
19726                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19727                 error "expected $bad_line bad lines, but got $bad_line_new"
19728                 return 1
19729         fi
19730
19731         if [ $expected_good -ne $good_line_new ]; then
19732                 error "expected $expected_good good lines, but got $good_line_new"
19733                 return 2
19734         fi
19735         true
19736 }
19737 run_test 170 "test lctl df to handle corrupted log ====================="
19738
19739 test_171() { # bug20592
19740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19741
19742         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19743         $LCTL set_param fail_loc=0x50e
19744         $LCTL set_param fail_val=3000
19745         multiop_bg_pause $DIR/$tfile O_s || true
19746         local MULTIPID=$!
19747         kill -USR1 $MULTIPID
19748         # cause log dump
19749         sleep 3
19750         wait $MULTIPID
19751         if dmesg | grep "recursive fault"; then
19752                 error "caught a recursive fault"
19753         fi
19754         $LCTL set_param fail_loc=0
19755         true
19756 }
19757 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19758
19759 test_172() {
19760
19761         #define OBD_FAIL_OBD_CLEANUP  0x60e
19762         $LCTL set_param fail_loc=0x60e
19763         umount $MOUNT || error "umount $MOUNT failed"
19764         stack_trap "mount_client $MOUNT"
19765
19766         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19767                 error "no client OBDs are remained"
19768
19769         $LCTL dl | while read devno state type name foo; do
19770                 case $type in
19771                 lov|osc|lmv|mdc)
19772                         $LCTL --device $name cleanup
19773                         $LCTL --device $name detach
19774                         ;;
19775                 *)
19776                         # skip server devices
19777                         ;;
19778                 esac
19779         done
19780
19781         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19782                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19783                 error "some client OBDs are still remained"
19784         fi
19785
19786 }
19787 run_test 172 "manual device removal with lctl cleanup/detach ======"
19788
19789 # it would be good to share it with obdfilter-survey/iokit-libecho code
19790 setup_obdecho_osc () {
19791         local rc=0
19792         local ost_nid=$1
19793         local obdfilter_name=$2
19794         echo "Creating new osc for $obdfilter_name on $ost_nid"
19795         # make sure we can find loopback nid
19796         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19797
19798         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19799                            ${obdfilter_name}_osc_UUID || rc=2; }
19800         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19801                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19802         return $rc
19803 }
19804
19805 cleanup_obdecho_osc () {
19806         local obdfilter_name=$1
19807         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19808         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19809         return 0
19810 }
19811
19812 obdecho_test() {
19813         local OBD=$1
19814         local node=$2
19815         local pages=${3:-64}
19816         local rc=0
19817         local id
19818
19819         local count=10
19820         local obd_size=$(get_obd_size $node $OBD)
19821         local page_size=$(get_page_size $node)
19822         if [[ -n "$obd_size" ]]; then
19823                 local new_count=$((obd_size / (pages * page_size / 1024)))
19824                 [[ $new_count -ge $count ]] || count=$new_count
19825         fi
19826
19827         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19828         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19829                            rc=2; }
19830         if [ $rc -eq 0 ]; then
19831             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19832             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19833         fi
19834         echo "New object id is $id"
19835         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19836                            rc=4; }
19837         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19838                            "test_brw $count w v $pages $id" || rc=4; }
19839         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19840                            rc=4; }
19841         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19842                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19843         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19844                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19845         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19846         return $rc
19847 }
19848
19849 test_180a() {
19850         skip "obdecho on osc is no longer supported"
19851 }
19852 run_test 180a "test obdecho on osc"
19853
19854 test_180b() {
19855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19856         remote_ost_nodsh && skip "remote OST with nodsh"
19857
19858         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19859                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19860                 error "failed to load module obdecho"
19861
19862         local target=$(do_facet ost1 $LCTL dl |
19863                        awk '/obdfilter/ { print $4; exit; }')
19864
19865         if [ -n "$target" ]; then
19866                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19867         else
19868                 do_facet ost1 $LCTL dl
19869                 error "there is no obdfilter target on ost1"
19870         fi
19871 }
19872 run_test 180b "test obdecho directly on obdfilter"
19873
19874 test_180c() { # LU-2598
19875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19876         remote_ost_nodsh && skip "remote OST with nodsh"
19877         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19878                 skip "Need MDS version at least 2.4.0"
19879
19880         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19881                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19882                 error "failed to load module obdecho"
19883
19884         local target=$(do_facet ost1 $LCTL dl |
19885                        awk '/obdfilter/ { print $4; exit; }')
19886
19887         if [ -n "$target" ]; then
19888                 local pages=16384 # 64MB bulk I/O RPC size
19889
19890                 obdecho_test "$target" ost1 "$pages" ||
19891                         error "obdecho_test with pages=$pages failed with $?"
19892         else
19893                 do_facet ost1 $LCTL dl
19894                 error "there is no obdfilter target on ost1"
19895         fi
19896 }
19897 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19898
19899 test_181() { # bug 22177
19900         test_mkdir $DIR/$tdir
19901         # create enough files to index the directory
19902         createmany -o $DIR/$tdir/foobar 4000
19903         # print attributes for debug purpose
19904         lsattr -d .
19905         # open dir
19906         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19907         MULTIPID=$!
19908         # remove the files & current working dir
19909         unlinkmany $DIR/$tdir/foobar 4000
19910         rmdir $DIR/$tdir
19911         kill -USR1 $MULTIPID
19912         wait $MULTIPID
19913         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19914         return 0
19915 }
19916 run_test 181 "Test open-unlinked dir ========================"
19917
19918 test_182a() {
19919         local fcount=1000
19920         local tcount=10
19921
19922         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19923
19924         $LCTL set_param mdc.*.rpc_stats=clear
19925
19926         for (( i = 0; i < $tcount; i++ )) ; do
19927                 mkdir $DIR/$tdir/$i
19928         done
19929
19930         for (( i = 0; i < $tcount; i++ )) ; do
19931                 createmany -o $DIR/$tdir/$i/f- $fcount &
19932         done
19933         wait
19934
19935         for (( i = 0; i < $tcount; i++ )) ; do
19936                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19937         done
19938         wait
19939
19940         $LCTL get_param mdc.*.rpc_stats
19941
19942         rm -rf $DIR/$tdir
19943 }
19944 run_test 182a "Test parallel modify metadata operations from mdc"
19945
19946 test_182b() {
19947         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19948         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19949         local dcount=1000
19950         local tcount=10
19951         local stime
19952         local etime
19953         local delta
19954
19955         do_facet mds1 $LCTL list_param \
19956                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19957                 skip "MDS lacks parallel RPC handling"
19958
19959         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19960
19961         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19962                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19963
19964         stime=$(date +%s)
19965         createmany -i 0 -d $DIR/$tdir/t- $tcount
19966
19967         for (( i = 0; i < $tcount; i++ )) ; do
19968                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19969         done
19970         wait
19971         etime=$(date +%s)
19972         delta=$((etime - stime))
19973         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19974
19975         stime=$(date +%s)
19976         for (( i = 0; i < $tcount; i++ )) ; do
19977                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19978         done
19979         wait
19980         etime=$(date +%s)
19981         delta=$((etime - stime))
19982         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19983
19984         rm -rf $DIR/$tdir
19985
19986         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19987
19988         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19989
19990         stime=$(date +%s)
19991         createmany -i 0 -d $DIR/$tdir/t- $tcount
19992
19993         for (( i = 0; i < $tcount; i++ )) ; do
19994                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19995         done
19996         wait
19997         etime=$(date +%s)
19998         delta=$((etime - stime))
19999         echo "Time for file creation $delta sec for 1 RPC sent at a time"
20000
20001         stime=$(date +%s)
20002         for (( i = 0; i < $tcount; i++ )) ; do
20003                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
20004         done
20005         wait
20006         etime=$(date +%s)
20007         delta=$((etime - stime))
20008         echo "Time for file removal $delta sec for 1 RPC sent at a time"
20009
20010         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
20011 }
20012 run_test 182b "Test parallel modify metadata operations from osp"
20013
20014 test_183() { # LU-2275
20015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20016         remote_mds_nodsh && skip "remote MDS with nodsh"
20017         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
20018                 skip "Need MDS version at least 2.3.56"
20019
20020         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20021         echo aaa > $DIR/$tdir/$tfile
20022
20023 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
20024         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
20025
20026         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
20027         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
20028
20029         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20030
20031         # Flush negative dentry cache
20032         touch $DIR/$tdir/$tfile
20033
20034         # We are not checking for any leaked references here, they'll
20035         # become evident next time we do cleanup with module unload.
20036         rm -rf $DIR/$tdir
20037 }
20038 run_test 183 "No crash or request leak in case of strange dispositions ========"
20039
20040 # test suite 184 is for LU-2016, LU-2017
20041 test_184a() {
20042         check_swap_layouts_support
20043
20044         dir0=$DIR/$tdir/$testnum
20045         test_mkdir -p -c1 $dir0
20046         ref1=/etc/passwd
20047         ref2=/etc/group
20048         file1=$dir0/f1
20049         file2=$dir0/f2
20050         $LFS setstripe -c1 $file1
20051         cp $ref1 $file1
20052         $LFS setstripe -c2 $file2
20053         cp $ref2 $file2
20054         gen1=$($LFS getstripe -g $file1)
20055         gen2=$($LFS getstripe -g $file2)
20056
20057         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20058         gen=$($LFS getstripe -g $file1)
20059         [[ $gen1 != $gen ]] ||
20060                 error "Layout generation on $file1 does not change"
20061         gen=$($LFS getstripe -g $file2)
20062         [[ $gen2 != $gen ]] ||
20063                 error "Layout generation on $file2 does not change"
20064
20065         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20066         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20067
20068         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20069 }
20070 run_test 184a "Basic layout swap"
20071
20072 test_184b() {
20073         check_swap_layouts_support
20074
20075         dir0=$DIR/$tdir/$testnum
20076         mkdir -p $dir0 || error "creating dir $dir0"
20077         file1=$dir0/f1
20078         file2=$dir0/f2
20079         file3=$dir0/f3
20080         dir1=$dir0/d1
20081         dir2=$dir0/d2
20082         mkdir $dir1 $dir2
20083         $LFS setstripe -c1 $file1
20084         $LFS setstripe -c2 $file2
20085         $LFS setstripe -c1 $file3
20086         chown $RUNAS_ID $file3
20087         gen1=$($LFS getstripe -g $file1)
20088         gen2=$($LFS getstripe -g $file2)
20089
20090         $LFS swap_layouts $dir1 $dir2 &&
20091                 error "swap of directories layouts should fail"
20092         $LFS swap_layouts $dir1 $file1 &&
20093                 error "swap of directory and file layouts should fail"
20094         $RUNAS $LFS swap_layouts $file1 $file2 &&
20095                 error "swap of file we cannot write should fail"
20096         $LFS swap_layouts $file1 $file3 &&
20097                 error "swap of file with different owner should fail"
20098         /bin/true # to clear error code
20099 }
20100 run_test 184b "Forbidden layout swap (will generate errors)"
20101
20102 test_184c() {
20103         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20104         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20105         check_swap_layouts_support
20106         check_swap_layout_no_dom $DIR
20107
20108         local dir0=$DIR/$tdir/$testnum
20109         mkdir -p $dir0 || error "creating dir $dir0"
20110
20111         local ref1=$dir0/ref1
20112         local ref2=$dir0/ref2
20113         local file1=$dir0/file1
20114         local file2=$dir0/file2
20115         # create a file large enough for the concurrent test
20116         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20117         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20118         echo "ref file size: ref1($(stat -c %s $ref1))," \
20119              "ref2($(stat -c %s $ref2))"
20120
20121         cp $ref2 $file2
20122         dd if=$ref1 of=$file1 bs=16k &
20123         local DD_PID=$!
20124
20125         # Make sure dd starts to copy file, but wait at most 5 seconds
20126         local loops=0
20127         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20128
20129         $LFS swap_layouts $file1 $file2
20130         local rc=$?
20131         wait $DD_PID
20132         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20133         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20134
20135         # how many bytes copied before swapping layout
20136         local copied=$(stat -c %s $file2)
20137         local remaining=$(stat -c %s $ref1)
20138         remaining=$((remaining - copied))
20139         echo "Copied $copied bytes before swapping layout..."
20140
20141         cmp -n $copied $file1 $ref2 | grep differ &&
20142                 error "Content mismatch [0, $copied) of ref2 and file1"
20143         cmp -n $copied $file2 $ref1 ||
20144                 error "Content mismatch [0, $copied) of ref1 and file2"
20145         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20146                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20147
20148         # clean up
20149         rm -f $ref1 $ref2 $file1 $file2
20150 }
20151 run_test 184c "Concurrent write and layout swap"
20152
20153 test_184d() {
20154         check_swap_layouts_support
20155         check_swap_layout_no_dom $DIR
20156         [ -z "$(which getfattr 2>/dev/null)" ] &&
20157                 skip_env "no getfattr command"
20158
20159         local file1=$DIR/$tdir/$tfile-1
20160         local file2=$DIR/$tdir/$tfile-2
20161         local file3=$DIR/$tdir/$tfile-3
20162         local lovea1
20163         local lovea2
20164
20165         mkdir -p $DIR/$tdir
20166         touch $file1 || error "create $file1 failed"
20167         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20168                 error "create $file2 failed"
20169         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20170                 error "create $file3 failed"
20171         lovea1=$(get_layout_param $file1)
20172
20173         $LFS swap_layouts $file2 $file3 ||
20174                 error "swap $file2 $file3 layouts failed"
20175         $LFS swap_layouts $file1 $file2 ||
20176                 error "swap $file1 $file2 layouts failed"
20177
20178         lovea2=$(get_layout_param $file2)
20179         echo "$lovea1"
20180         echo "$lovea2"
20181         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20182
20183         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20184         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20185 }
20186 run_test 184d "allow stripeless layouts swap"
20187
20188 test_184e() {
20189         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20190                 skip "Need MDS version at least 2.6.94"
20191         check_swap_layouts_support
20192         check_swap_layout_no_dom $DIR
20193         [ -z "$(which getfattr 2>/dev/null)" ] &&
20194                 skip_env "no getfattr command"
20195
20196         local file1=$DIR/$tdir/$tfile-1
20197         local file2=$DIR/$tdir/$tfile-2
20198         local file3=$DIR/$tdir/$tfile-3
20199         local lovea
20200
20201         mkdir -p $DIR/$tdir
20202         touch $file1 || error "create $file1 failed"
20203         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20204                 error "create $file2 failed"
20205         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20206                 error "create $file3 failed"
20207
20208         $LFS swap_layouts $file1 $file2 ||
20209                 error "swap $file1 $file2 layouts failed"
20210
20211         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20212         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20213
20214         echo 123 > $file1 || error "Should be able to write into $file1"
20215
20216         $LFS swap_layouts $file1 $file3 ||
20217                 error "swap $file1 $file3 layouts failed"
20218
20219         echo 123 > $file1 || error "Should be able to write into $file1"
20220
20221         rm -rf $file1 $file2 $file3
20222 }
20223 run_test 184e "Recreate layout after stripeless layout swaps"
20224
20225 test_184f() {
20226         # Create a file with name longer than sizeof(struct stat) ==
20227         # 144 to see if we can get chars from the file name to appear
20228         # in the returned striping. Note that 'f' == 0x66.
20229         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20230
20231         mkdir -p $DIR/$tdir
20232         mcreate $DIR/$tdir/$file
20233         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20234                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20235         fi
20236 }
20237 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20238
20239 test_185() { # LU-2441
20240         # LU-3553 - no volatile file support in old servers
20241         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20242                 skip "Need MDS version at least 2.3.60"
20243
20244         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20245         touch $DIR/$tdir/spoo
20246         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20247         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20248                 error "cannot create/write a volatile file"
20249         [ "$FILESET" == "" ] &&
20250         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20251                 error "FID is still valid after close"
20252
20253         multiop_bg_pause $DIR/$tdir Vw4096_c
20254         local multi_pid=$!
20255
20256         local OLD_IFS=$IFS
20257         IFS=":"
20258         local fidv=($fid)
20259         IFS=$OLD_IFS
20260         # assume that the next FID for this client is sequential, since stdout
20261         # is unfortunately eaten by multiop_bg_pause
20262         local n=$((${fidv[1]} + 1))
20263         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20264         if [ "$FILESET" == "" ]; then
20265                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20266                         error "FID is missing before close"
20267         fi
20268         kill -USR1 $multi_pid
20269         # 1 second delay, so if mtime change we will see it
20270         sleep 1
20271         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20272         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20273 }
20274 run_test 185 "Volatile file support"
20275
20276 function create_check_volatile() {
20277         local idx=$1
20278         local tgt
20279
20280         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20281         local PID=$!
20282         sleep 1
20283         local FID=$(cat /tmp/${tfile}.fid)
20284         [ "$FID" == "" ] && error "can't get FID for volatile"
20285         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20286         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20287         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20288         kill -USR1 $PID
20289         wait
20290         sleep 1
20291         cancel_lru_locks mdc # flush opencache
20292         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20293         return 0
20294 }
20295
20296 test_185a(){
20297         # LU-12516 - volatile creation via .lustre
20298         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20299                 skip "Need MDS version at least 2.3.55"
20300
20301         create_check_volatile 0
20302         [ $MDSCOUNT -lt 2 ] && return 0
20303
20304         # DNE case
20305         create_check_volatile 1
20306
20307         return 0
20308 }
20309 run_test 185a "Volatile file creation in .lustre/fid/"
20310
20311 test_187a() {
20312         remote_mds_nodsh && skip "remote MDS with nodsh"
20313         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20314                 skip "Need MDS version at least 2.3.0"
20315
20316         local dir0=$DIR/$tdir/$testnum
20317         mkdir -p $dir0 || error "creating dir $dir0"
20318
20319         local file=$dir0/file1
20320         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20321         stack_trap "rm -f $file"
20322         local dv1=$($LFS data_version $file)
20323         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20324         local dv2=$($LFS data_version $file)
20325         [[ $dv1 != $dv2 ]] ||
20326                 error "data version did not change on write $dv1 == $dv2"
20327 }
20328 run_test 187a "Test data version change"
20329
20330 test_187b() {
20331         remote_mds_nodsh && skip "remote MDS with nodsh"
20332         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20333                 skip "Need MDS version at least 2.3.0"
20334
20335         local dir0=$DIR/$tdir/$testnum
20336         mkdir -p $dir0 || error "creating dir $dir0"
20337
20338         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20339         [[ ${DV[0]} != ${DV[1]} ]] ||
20340                 error "data version did not change on write"\
20341                       " ${DV[0]} == ${DV[1]}"
20342
20343         # clean up
20344         rm -f $file1
20345 }
20346 run_test 187b "Test data version change on volatile file"
20347
20348 test_200() {
20349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20350         remote_mgs_nodsh && skip "remote MGS with nodsh"
20351         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20352
20353         local POOL=${POOL:-cea1}
20354         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20355         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20356         # Pool OST targets
20357         local first_ost=0
20358         local last_ost=$(($OSTCOUNT - 1))
20359         local ost_step=2
20360         local ost_list=$(seq $first_ost $ost_step $last_ost)
20361         local ost_range="$first_ost $last_ost $ost_step"
20362         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20363         local file_dir=$POOL_ROOT/file_tst
20364         local subdir=$test_path/subdir
20365         local rc=0
20366
20367         while : ; do
20368                 # former test_200a test_200b
20369                 pool_add $POOL                          || { rc=$? ; break; }
20370                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20371                 # former test_200c test_200d
20372                 mkdir -p $test_path
20373                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20374                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20375                 mkdir -p $subdir
20376                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20377                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20378                                                         || { rc=$? ; break; }
20379                 # former test_200e test_200f
20380                 local files=$((OSTCOUNT*3))
20381                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20382                                                         || { rc=$? ; break; }
20383                 pool_create_files $POOL $file_dir $files "$ost_list" \
20384                                                         || { rc=$? ; break; }
20385                 # former test_200g test_200h
20386                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20387                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20388
20389                 # former test_201a test_201b test_201c
20390                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20391
20392                 local f=$test_path/$tfile
20393                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20394                 pool_remove $POOL $f                    || { rc=$? ; break; }
20395                 break
20396         done
20397
20398         destroy_test_pools
20399
20400         return $rc
20401 }
20402 run_test 200 "OST pools"
20403
20404 # usage: default_attr <count | size | offset>
20405 default_attr() {
20406         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20407 }
20408
20409 # usage: check_default_stripe_attr
20410 check_default_stripe_attr() {
20411         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20412         case $1 in
20413         --stripe-count|-c)
20414                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20415         --stripe-size|-S)
20416                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20417         --stripe-index|-i)
20418                 EXPECTED=-1;;
20419         *)
20420                 error "unknown getstripe attr '$1'"
20421         esac
20422
20423         [ $ACTUAL == $EXPECTED ] ||
20424                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20425 }
20426
20427 test_204a() {
20428         test_mkdir $DIR/$tdir
20429         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20430
20431         check_default_stripe_attr --stripe-count
20432         check_default_stripe_attr --stripe-size
20433         check_default_stripe_attr --stripe-index
20434 }
20435 run_test 204a "Print default stripe attributes"
20436
20437 test_204b() {
20438         test_mkdir $DIR/$tdir
20439         $LFS setstripe --stripe-count 1 $DIR/$tdir
20440
20441         check_default_stripe_attr --stripe-size
20442         check_default_stripe_attr --stripe-index
20443 }
20444 run_test 204b "Print default stripe size and offset"
20445
20446 test_204c() {
20447         test_mkdir $DIR/$tdir
20448         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20449
20450         check_default_stripe_attr --stripe-count
20451         check_default_stripe_attr --stripe-index
20452 }
20453 run_test 204c "Print default stripe count and offset"
20454
20455 test_204d() {
20456         test_mkdir $DIR/$tdir
20457         $LFS setstripe --stripe-index 0 $DIR/$tdir
20458
20459         check_default_stripe_attr --stripe-count
20460         check_default_stripe_attr --stripe-size
20461 }
20462 run_test 204d "Print default stripe count and size"
20463
20464 test_204e() {
20465         test_mkdir $DIR/$tdir
20466         $LFS setstripe -d $DIR/$tdir
20467
20468         # LU-16904 check if root is set as PFL layout
20469         local numcomp=$($LFS getstripe --component-count $MOUNT)
20470
20471         if [[ $numcomp -gt 0 ]]; then
20472                 check_default_stripe_attr --stripe-count
20473         else
20474                 check_default_stripe_attr --stripe-count --raw
20475         fi
20476         check_default_stripe_attr --stripe-size --raw
20477         check_default_stripe_attr --stripe-index --raw
20478 }
20479 run_test 204e "Print raw stripe attributes"
20480
20481 test_204f() {
20482         test_mkdir $DIR/$tdir
20483         $LFS setstripe --stripe-count 1 $DIR/$tdir
20484
20485         check_default_stripe_attr --stripe-size --raw
20486         check_default_stripe_attr --stripe-index --raw
20487 }
20488 run_test 204f "Print raw stripe size and offset"
20489
20490 test_204g() {
20491         test_mkdir $DIR/$tdir
20492         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20493
20494         check_default_stripe_attr --stripe-count --raw
20495         check_default_stripe_attr --stripe-index --raw
20496 }
20497 run_test 204g "Print raw stripe count and offset"
20498
20499 test_204h() {
20500         test_mkdir $DIR/$tdir
20501         $LFS setstripe --stripe-index 0 $DIR/$tdir
20502
20503         check_default_stripe_attr --stripe-count --raw
20504         check_default_stripe_attr --stripe-size --raw
20505 }
20506 run_test 204h "Print raw stripe count and size"
20507
20508 # Figure out which job scheduler is being used, if any,
20509 # or use a fake one
20510 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20511         JOBENV=SLURM_JOB_ID
20512 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20513         JOBENV=LSB_JOBID
20514 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20515         JOBENV=PBS_JOBID
20516 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20517         JOBENV=LOADL_STEP_ID
20518 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20519         JOBENV=JOB_ID
20520 else
20521         $LCTL list_param jobid_name > /dev/null 2>&1
20522         if [ $? -eq 0 ]; then
20523                 JOBENV=nodelocal
20524         else
20525                 JOBENV=FAKE_JOBID
20526         fi
20527 fi
20528 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20529
20530 verify_jobstats() {
20531         local cmd=($1)
20532         shift
20533         local facets="$@"
20534
20535 # we don't really need to clear the stats for this test to work, since each
20536 # command has a unique jobid, but it makes debugging easier if needed.
20537 #       for facet in $facets; do
20538 #               local dev=$(convert_facet2label $facet)
20539 #               # clear old jobstats
20540 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20541 #       done
20542
20543         # use a new JobID for each test, or we might see an old one
20544         [ "$JOBENV" = "FAKE_JOBID" ] &&
20545                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20546
20547         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20548
20549         [ "$JOBENV" = "nodelocal" ] && {
20550                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20551                 $LCTL set_param jobid_name=$FAKE_JOBID
20552                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20553         }
20554
20555         log "Test: ${cmd[*]}"
20556         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20557
20558         if [ $JOBENV = "FAKE_JOBID" ]; then
20559                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20560         else
20561                 ${cmd[*]}
20562         fi
20563
20564         # all files are created on OST0000
20565         for facet in $facets; do
20566                 local stats="*.$(convert_facet2label $facet).job_stats"
20567
20568                 # strip out libtool wrappers for in-tree executables
20569                 if (( $(do_facet $facet lctl get_param $stats |
20570                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20571                         do_facet $facet lctl get_param $stats
20572                         error "No jobstats for $JOBVAL found on $facet::$stats"
20573                 fi
20574         done
20575 }
20576
20577 jobstats_set() {
20578         local new_jobenv=$1
20579
20580         set_persistent_param_and_check client "jobid_var" \
20581                 "$FSNAME.sys.jobid_var" $new_jobenv
20582 }
20583
20584 test_205a() { # Job stats
20585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20586         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20587                 skip "Need MDS version with at least 2.7.1"
20588         remote_mgs_nodsh && skip "remote MGS with nodsh"
20589         remote_mds_nodsh && skip "remote MDS with nodsh"
20590         remote_ost_nodsh && skip "remote OST with nodsh"
20591         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20592                 skip "Server doesn't support jobstats"
20593         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20594
20595         local old_jobenv=$($LCTL get_param -n jobid_var)
20596         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20597         stack_trap "jobstats_set $old_jobenv" EXIT
20598
20599         changelog_register
20600
20601         local old_jobid_name=$($LCTL get_param jobid_name)
20602         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20603
20604         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20605                                 mdt.*.job_cleanup_interval | head -n 1)
20606         local new_interval=5
20607         do_facet $SINGLEMDS \
20608                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20609         stack_trap "do_facet $SINGLEMDS \
20610                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20611         local start=$SECONDS
20612
20613         local cmd
20614         # mkdir
20615         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20616         verify_jobstats "$cmd" "$SINGLEMDS"
20617         # rmdir
20618         cmd="rmdir $DIR/$tdir"
20619         verify_jobstats "$cmd" "$SINGLEMDS"
20620         # mkdir on secondary MDT
20621         if [ $MDSCOUNT -gt 1 ]; then
20622                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20623                 verify_jobstats "$cmd" "mds2"
20624         fi
20625         # mknod
20626         cmd="mknod $DIR/$tfile c 1 3"
20627         verify_jobstats "$cmd" "$SINGLEMDS"
20628         # unlink
20629         cmd="rm -f $DIR/$tfile"
20630         verify_jobstats "$cmd" "$SINGLEMDS"
20631         # create all files on OST0000 so verify_jobstats can find OST stats
20632         # open & close
20633         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20634         verify_jobstats "$cmd" "$SINGLEMDS"
20635         # setattr
20636         cmd="touch $DIR/$tfile"
20637         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20638         # write
20639         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20640         verify_jobstats "$cmd" "ost1"
20641         # read
20642         cancel_lru_locks osc
20643         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20644         verify_jobstats "$cmd" "ost1"
20645         # truncate
20646         cmd="$TRUNCATE $DIR/$tfile 0"
20647         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20648         # rename
20649         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20650         verify_jobstats "$cmd" "$SINGLEMDS"
20651         # jobstats expiry - sleep until old stats should be expired
20652         local left=$((new_interval + 5 - (SECONDS - start)))
20653         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20654                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20655                         "0" $left
20656         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20657         verify_jobstats "$cmd" "$SINGLEMDS"
20658         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20659             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20660
20661         # Ensure that jobid are present in changelog (if supported by MDS)
20662         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20663                 changelog_dump | tail -10
20664                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20665                 [ $jobids -eq 9 ] ||
20666                         error "Wrong changelog jobid count $jobids != 9"
20667
20668                 # LU-5862
20669                 JOBENV="disable"
20670                 jobstats_set $JOBENV
20671                 touch $DIR/$tfile
20672                 changelog_dump | grep $tfile
20673                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20674                 [ $jobids -eq 0 ] ||
20675                         error "Unexpected jobids when jobid_var=$JOBENV"
20676         fi
20677
20678         # test '%j' access to environment variable - if supported
20679         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20680                 JOBENV="JOBCOMPLEX"
20681                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20682
20683                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20684         fi
20685
20686         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20687                 JOBENV="JOBCOMPLEX"
20688                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20689
20690                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20691         fi
20692
20693         # test '%j' access to per-session jobid - if supported
20694         if lctl list_param jobid_this_session > /dev/null 2>&1
20695         then
20696                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20697                 lctl set_param jobid_this_session=$USER
20698
20699                 JOBENV="JOBCOMPLEX"
20700                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20701
20702                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20703         fi
20704 }
20705 run_test 205a "Verify job stats"
20706
20707 # LU-13117, LU-13597, LU-16599
20708 test_205b() {
20709         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20710                 skip "Need MDS version at least 2.13.54.91"
20711
20712         local job_stats="mdt.*.job_stats"
20713         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20714
20715         do_facet mds1 $LCTL set_param $job_stats=clear
20716
20717         # Setting jobid_var to USER might not be supported
20718         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20719         $LCTL set_param jobid_var=USER || true
20720         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20721         $LCTL set_param jobid_name="%j.%e.%u"
20722
20723         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20724         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20725                 { do_facet mds1 $LCTL get_param $job_stats;
20726                   error "Unexpected jobid found"; }
20727         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20728                 { do_facet mds1 $LCTL get_param $job_stats;
20729                   error "wrong job_stats format found"; }
20730
20731         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20732                 echo "MDS does not yet escape jobid" && return 0
20733
20734         mkdir_on_mdt0 $DIR/$tdir
20735         $LCTL set_param jobid_var=TEST205b
20736         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20737         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20738                       awk '/has\\x20sp/ {print $3}')
20739         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20740                   error "jobid not escaped"; }
20741
20742         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20743                 # need to run such a command on mds1:
20744                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20745                 #
20746                 # there might be multiple MDTs on single mds server, so need to
20747                 # specifiy MDT0000. Or the command will fail due to other MDTs
20748                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20749                         error "cannot clear escaped jobid in job_stats";
20750         else
20751                 echo "MDS does not support clearing escaped jobid"
20752         fi
20753 }
20754 run_test 205b "Verify job stats jobid and output format"
20755
20756 # LU-13733
20757 test_205c() {
20758         $LCTL set_param llite.*.stats=0
20759         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20760         $LCTL get_param llite.*.stats
20761         $LCTL get_param llite.*.stats | grep \
20762                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20763                         error "wrong client stats format found"
20764 }
20765 run_test 205c "Verify client stats format"
20766
20767 test_205d() {
20768         local file=$DIR/$tdir/$tfile
20769
20770         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20771                 skip "need lustre >= 2.15.53 for lljobstat"
20772         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20773                 skip "need lustre >= 2.15.53 for lljobstat"
20774         verify_yaml_available || skip_env "YAML verification not installed"
20775
20776         test_mkdir -i 0 $DIR/$tdir
20777         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20778         stack_trap "rm -rf $DIR/$tdir"
20779
20780         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20781                 error "failed to write data to $file"
20782         mv $file $file.2
20783
20784         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20785         echo -n 'verify rename_stats...'
20786         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20787                 verify_yaml || error "rename_stats is not valid YAML"
20788         echo " OK"
20789
20790         echo -n 'verify mdt job_stats...'
20791         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20792                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20793         echo " OK"
20794
20795         echo -n 'verify ost job_stats...'
20796         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20797                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20798         echo " OK"
20799 }
20800 run_test 205d "verify the format of some stats files"
20801
20802 test_205e() {
20803         local ops_comma
20804         local file=$DIR/$tdir/$tfile
20805         local -a cli_params
20806
20807         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20808                 skip "need lustre >= 2.15.53 for lljobstat"
20809         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20810                 skip "need lustre >= 2.15.53 for lljobstat"
20811         verify_yaml_available || skip_env "YAML verification not installed"
20812
20813         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20814         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20815         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20816
20817         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20818         stack_trap "rm -rf $DIR/$tdir"
20819
20820         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20821                 error "failed to create $file on ost1"
20822         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20823                 error "failed to write data to $file"
20824
20825         do_facet mds1 "$LCTL get_param *.*.job_stats"
20826         do_facet ost1 "$LCTL get_param *.*.job_stats"
20827
20828         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20829         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20830                 error "The output of lljobstat is not an valid YAML"
20831
20832         # verify that job dd.0 does exist and has some ops on ost1
20833         # typically this line is like:
20834         # - 205e.dd.0:            {ops: 20, ...}
20835         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20836                     awk '$2=="205e.dd.0:" {print $4}')
20837
20838         (( ${ops_comma%,} >= 10 )) ||
20839                 error "cannot find job 205e.dd.0 with ops >= 10"
20840 }
20841 run_test 205e "verify the output of lljobstat"
20842
20843 test_205f() {
20844         verify_yaml_available || skip_env "YAML verification not installed"
20845
20846         # check both qos_ost_weights and qos_mdt_weights
20847         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20848         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20849                 error "qos_ost_weights is not valid YAML"
20850 }
20851 run_test 205f "verify qos_ost_weights YAML format "
20852
20853 __test_205_jobstats_dump() {
20854         local -a pids
20855         local nbr_instance=$1
20856
20857         while true; do
20858                 if (( ${#pids[@]} >= nbr_instance )); then
20859                         wait ${pids[@]}
20860                         pids=()
20861                 fi
20862
20863                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20864                 pids+=( $! )
20865         done
20866 }
20867
20868 __test_205_cleanup() {
20869         kill $@
20870         # Clear all job entries
20871         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20872 }
20873
20874 test_205g() {
20875         local -a mds1_params
20876         local -a cli_params
20877         local pids
20878         local interval=5
20879
20880         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20881         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20882         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20883
20884         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20885         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20886         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20887
20888         # start jobs loop
20889         export TEST205G_ID=205g
20890         stack_trap "unset TEST205G_ID" EXIT
20891         while true; do
20892                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20893         done & pids="$! "
20894
20895         __test_205_jobstats_dump 4 & pids+="$! "
20896         stack_trap "__test_205_cleanup $pids" EXIT INT
20897
20898         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20899 }
20900 run_test 205g "stress test for job_stats procfile"
20901
20902 test_205h() {
20903         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20904                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20905         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20906
20907         local dir=$DIR/$tdir
20908         local f=$dir/$tfile
20909         local f2=$dir/$tfile-2
20910         local f3=$dir/$tfile-3
20911         local subdir=$DIR/dir
20912         local val
20913
20914         local mdts=$(comma_list $(mdts_nodes))
20915         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20916         local client_saved=$($LCTL get_param -n jobid_var)
20917
20918         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20919         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20920
20921         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20922                 error "failed to set job_xattr parameter to user.job"
20923         $LCTL set_param jobid_var=procname.uid ||
20924                 error "failed to set jobid_var parameter"
20925
20926         test_mkdir $dir
20927
20928         touch $f
20929         val=$(getfattr -n user.job $f | grep user.job)
20930         [[ $val = user.job=\"touch.0\" ]] ||
20931                 error "expected user.job=\"touch.0\", got '$val'"
20932
20933         mkdir $subdir
20934         val=$(getfattr -n user.job $subdir | grep user.job)
20935         [[ $val = user.job=\"mkdir.0\" ]] ||
20936                 error "expected user.job=\"mkdir.0\", got '$val'"
20937
20938         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20939                 error "failed to set job_xattr parameter to NONE"
20940
20941         touch $f2
20942         val=$(getfattr -d $f2)
20943         [[ -z $val ]] ||
20944                 error "expected no user xattr, got '$val'"
20945
20946         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20947                 error "failed to set job_xattr parameter to trusted.job"
20948
20949         touch $f3
20950         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20951         [[ $val = trusted.job=\"touch.0\" ]] ||
20952                 error "expected trusted.job=\"touch.0\", got '$val'"
20953 }
20954 run_test 205h "check jobid xattr is stored correctly"
20955
20956 test_205i() {
20957         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20958                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20959
20960         local mdts=$(comma_list $(mdts_nodes))
20961         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20962
20963         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20964
20965         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20966                 error "failed to set mdt.*.job_xattr to user.1234567"
20967
20968         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20969                 error "failed to reject too long job_xattr name"
20970
20971         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20972                 error "failed to reject job_xattr name in bad format"
20973
20974         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20975                 error "failed to reject job_xattr name with invalid character"
20976
20977         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20978                         xargs $LCTL set_param" &&
20979                 error "failed to reject job_xattr name with non-ascii character"
20980
20981         return 0
20982 }
20983 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20984
20985 # LU-1480, LU-1773 and LU-1657
20986 test_206() {
20987         mkdir -p $DIR/$tdir
20988         $LFS setstripe -c -1 $DIR/$tdir
20989 #define OBD_FAIL_LOV_INIT 0x1403
20990         $LCTL set_param fail_loc=0xa0001403
20991         $LCTL set_param fail_val=1
20992         touch $DIR/$tdir/$tfile || true
20993 }
20994 run_test 206 "fail lov_init_raid0() doesn't lbug"
20995
20996 test_207a() {
20997         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20998         local fsz=`stat -c %s $DIR/$tfile`
20999         cancel_lru_locks mdc
21000
21001         # do not return layout in getattr intent
21002 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
21003         $LCTL set_param fail_loc=0x170
21004         local sz=`stat -c %s $DIR/$tfile`
21005
21006         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
21007
21008         rm -rf $DIR/$tfile
21009 }
21010 run_test 207a "can refresh layout at glimpse"
21011
21012 test_207b() {
21013         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21014         local cksum=`md5sum $DIR/$tfile`
21015         local fsz=`stat -c %s $DIR/$tfile`
21016         cancel_lru_locks mdc
21017         cancel_lru_locks osc
21018
21019         # do not return layout in getattr intent
21020 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
21021         $LCTL set_param fail_loc=0x171
21022
21023         # it will refresh layout after the file is opened but before read issues
21024         echo checksum is "$cksum"
21025         echo "$cksum" |md5sum -c --quiet || error "file differs"
21026
21027         rm -rf $DIR/$tfile
21028 }
21029 run_test 207b "can refresh layout at open"
21030
21031 test_208() {
21032         # FIXME: in this test suite, only RD lease is used. This is okay
21033         # for now as only exclusive open is supported. After generic lease
21034         # is done, this test suite should be revised. - Jinshan
21035
21036         remote_mds_nodsh && skip "remote MDS with nodsh"
21037         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21038                 skip "Need MDS version at least 2.4.52"
21039
21040         echo "==== test 1: verify get lease work"
21041         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21042
21043         echo "==== test 2: verify lease can be broken by upcoming open"
21044         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21045         local PID=$!
21046         sleep 2
21047
21048         $MULTIOP $DIR/$tfile oO_RDWR:c
21049         kill -USR1 $PID && wait $PID || error "break lease error"
21050
21051         echo "==== test 3: verify lease can't be granted if an open already exists"
21052         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21053         local PID=$!
21054         sleep 2
21055
21056         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21057         kill -USR1 $PID && wait $PID || error "open file error"
21058
21059         echo "==== test 4: lease can sustain over recovery"
21060         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21061         PID=$!
21062         sleep 2
21063
21064         fail mds1
21065
21066         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21067
21068         echo "==== test 5: lease broken can't be regained by replay"
21069         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21070         PID=$!
21071         sleep 2
21072
21073         # open file to break lease and then recovery
21074         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21075         fail mds1
21076
21077         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21078
21079         rm -f $DIR/$tfile
21080 }
21081 run_test 208 "Exclusive open"
21082
21083 test_209() {
21084         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21085                 skip_env "must have disp_stripe"
21086
21087         touch $DIR/$tfile
21088         sync; sleep 5; sync;
21089
21090         echo 3 > /proc/sys/vm/drop_caches
21091         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21092                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21093         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21094
21095         # open/close 500 times
21096         for i in $(seq 500); do
21097                 cat $DIR/$tfile
21098         done
21099
21100         echo 3 > /proc/sys/vm/drop_caches
21101         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21102                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21103         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21104
21105         echo "before: $req_before, after: $req_after"
21106         [ $((req_after - req_before)) -ge 300 ] &&
21107                 error "open/close requests are not freed"
21108         return 0
21109 }
21110 run_test 209 "read-only open/close requests should be freed promptly"
21111
21112 test_210() {
21113         local pid
21114
21115         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21116         pid=$!
21117         sleep 1
21118
21119         $LFS getstripe $DIR/$tfile
21120         kill -USR1 $pid
21121         wait $pid || error "multiop failed"
21122
21123         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21124         pid=$!
21125         sleep 1
21126
21127         $LFS getstripe $DIR/$tfile
21128         kill -USR1 $pid
21129         wait $pid || error "multiop failed"
21130 }
21131 run_test 210 "lfs getstripe does not break leases"
21132
21133 function test_211() {
21134         local PID
21135         local id
21136         local rc
21137
21138         stack_trap "rm -f $DIR/$tfile" EXIT
21139         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21140                 error "can't create file"
21141         $LFS mirror extend -N $DIR/$tfile ||
21142                 error "can't create a replica"
21143         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21144         $LFS getstripe $DIR/$tfile
21145         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21146         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21147
21148         $MULTIOP $DIR/$tfile OeW_E+eUc &
21149         PID=$!
21150         sleep 0.3
21151
21152         id=$($LFS getstripe $DIR/$tfile |
21153                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21154         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21155                 error "removed last in-sync replica?"
21156
21157         kill -USR1 $PID
21158         wait $PID
21159         (( $? == 0 )) || error "failed split broke the lease"
21160 }
21161 run_test 211 "failed mirror split doesn't break write lease"
21162
21163 test_212() {
21164         size=`date +%s`
21165         size=$((size % 8192 + 1))
21166         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21167         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21168         rm -f $DIR/f212 $DIR/f212.xyz
21169 }
21170 run_test 212 "Sendfile test ============================================"
21171
21172 test_213() {
21173         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21174         cancel_lru_locks osc
21175         lctl set_param fail_loc=0x8000040f
21176         # generate a read lock
21177         cat $DIR/$tfile > /dev/null
21178         # write to the file, it will try to cancel the above read lock.
21179         cat /etc/hosts >> $DIR/$tfile
21180 }
21181 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21182
21183 test_214() { # for bug 20133
21184         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21185         for (( i=0; i < 340; i++ )) ; do
21186                 touch $DIR/$tdir/d214c/a$i
21187         done
21188
21189         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21190         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21191         ls $DIR/d214c || error "ls $DIR/d214c failed"
21192         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21193         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21194 }
21195 run_test 214 "hash-indexed directory test - bug 20133"
21196
21197 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21198 create_lnet_proc_files() {
21199         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21200 }
21201
21202 # counterpart of create_lnet_proc_files
21203 remove_lnet_proc_files() {
21204         rm -f $TMP/lnet_$1.sys
21205 }
21206
21207 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21208 # 3rd arg as regexp for body
21209 check_lnet_proc_stats() {
21210         local l=$(cat "$TMP/lnet_$1" |wc -l)
21211         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21212
21213         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21214 }
21215
21216 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21217 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21218 # optional and can be regexp for 2nd line (lnet.routes case)
21219 check_lnet_proc_entry() {
21220         local blp=2          # blp stands for 'position of 1st line of body'
21221         [ -z "$5" ] || blp=3 # lnet.routes case
21222
21223         local l=$(cat "$TMP/lnet_$1" |wc -l)
21224         # subtracting one from $blp because the body can be empty
21225         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21226
21227         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21228                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21229
21230         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21231                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21232
21233         # bail out if any unexpected line happened
21234         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21235         [ "$?" != 0 ] || error "$2 misformatted"
21236 }
21237
21238 test_215() { # for bugs 18102, 21079, 21517
21239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21240
21241         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21242         local P='[1-9][0-9]*'           # positive numeric
21243         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21244         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21245         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21246         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21247         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21248         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21249
21250         local L1 # regexp for 1st line
21251         local L2 # regexp for 2nd line (optional)
21252         local BR # regexp for the rest (body)
21253
21254         # lnet.stats should look as 11 space-separated non-negative numerics
21255         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21256         create_lnet_proc_files "stats"
21257         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21258         remove_lnet_proc_files "stats"
21259
21260         # lnet.routes should look like this:
21261         # Routing disabled/enabled
21262         # net hops priority state router
21263         # where net is a string like tcp0, hops > 0, priority >= 0,
21264         # state is up/down,
21265         # router is a string like 192.168.1.1@tcp2
21266         L1="^Routing (disabled|enabled)$"
21267         L2="^net +hops +priority +state +router$"
21268         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21269         create_lnet_proc_files "routes"
21270         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21271         remove_lnet_proc_files "routes"
21272
21273         # lnet.routers should look like this:
21274         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21275         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21276         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21277         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21278         L1="^ref +rtr_ref +alive +router$"
21279         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21280         create_lnet_proc_files "routers"
21281         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21282         remove_lnet_proc_files "routers"
21283
21284         # lnet.peers should look like this:
21285         # nid refs state last max rtr min tx min queue
21286         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21287         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21288         # numeric (0 or >0 or <0), queue >= 0.
21289         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21290         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21291         create_lnet_proc_files "peers"
21292         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21293         remove_lnet_proc_files "peers"
21294
21295         # lnet.buffers  should look like this:
21296         # pages count credits min
21297         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21298         L1="^pages +count +credits +min$"
21299         BR="^ +$N +$N +$I +$I$"
21300         create_lnet_proc_files "buffers"
21301         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21302         remove_lnet_proc_files "buffers"
21303
21304         # lnet.nis should look like this:
21305         # nid status alive refs peer rtr max tx min
21306         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21307         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21308         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21309         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21310         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21311         create_lnet_proc_files "nis"
21312         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21313         remove_lnet_proc_files "nis"
21314
21315         # can we successfully write to lnet.stats?
21316         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21317 }
21318 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21319
21320 test_216() { # bug 20317
21321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21322         remote_ost_nodsh && skip "remote OST with nodsh"
21323
21324         local node
21325         local facets=$(get_facets OST)
21326         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21327
21328         save_lustre_params client "osc.*.contention_seconds" > $p
21329         save_lustre_params $facets \
21330                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21331         save_lustre_params $facets \
21332                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21333         save_lustre_params $facets \
21334                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21335         clear_stats osc.*.osc_stats
21336
21337         # agressive lockless i/o settings
21338         do_nodes $(comma_list $(osts_nodes)) \
21339                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21340                         ldlm.namespaces.filter-*.contended_locks=0 \
21341                         ldlm.namespaces.filter-*.contention_seconds=60"
21342         lctl set_param -n osc.*.contention_seconds=60
21343
21344         $DIRECTIO write $DIR/$tfile 0 10 4096
21345         $CHECKSTAT -s 40960 $DIR/$tfile
21346
21347         # disable lockless i/o
21348         do_nodes $(comma_list $(osts_nodes)) \
21349                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21350                         ldlm.namespaces.filter-*.contended_locks=32 \
21351                         ldlm.namespaces.filter-*.contention_seconds=0"
21352         lctl set_param -n osc.*.contention_seconds=0
21353         clear_stats osc.*.osc_stats
21354
21355         dd if=/dev/zero of=$DIR/$tfile count=0
21356         $CHECKSTAT -s 0 $DIR/$tfile
21357
21358         restore_lustre_params <$p
21359         rm -f $p
21360         rm $DIR/$tfile
21361 }
21362 run_test 216 "check lockless direct write updates file size and kms correctly"
21363
21364 test_217() { # bug 22430
21365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21366
21367         local node
21368
21369         for node in $(nodes_list); do
21370                 local nid=$(host_nids_address $node $NETTYPE)
21371                 local node_ip=$(do_node $node getent ahostsv4 $node |
21372                                 awk '{ print $1; exit; }')
21373
21374                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21375                 # if hostname matches any NID, use hostname for better testing
21376                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21377                         echo "lctl ping node $node@$NETTYPE"
21378                         lctl ping $node@$NETTYPE ||
21379                                 error "ping $node@$NETTYPE failed rc=$?"
21380                 else # otherwise, at least test 'lctl ping' is working
21381                         echo "lctl ping nid $(h2nettype $nid)"
21382                         lctl ping $(h2nettype $nid) ||
21383                                 error "ping $(h2nettype $nid) failed rc=$?"
21384                         echo "skipping $node (no hyphen detected)"
21385                 fi
21386         done
21387
21388         return 0
21389 }
21390 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21391
21392 test_218() {
21393         # do directio so as not to populate the page cache
21394         log "creating a 10 Mb file"
21395         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21396                 error "multiop failed while creating a file"
21397         log "starting reads"
21398         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21399         log "truncating the file"
21400         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21401                 error "multiop failed while truncating the file"
21402         log "killing dd"
21403         kill %+ || true # reads might have finished
21404         echo "wait until dd is finished"
21405         wait
21406         log "removing the temporary file"
21407         rm -rf $DIR/$tfile || error "tmp file removal failed"
21408 }
21409 run_test 218 "parallel read and truncate should not deadlock"
21410
21411 test_219() {
21412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21413
21414         # write one partial page
21415         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21416         # set no grant so vvp_io_commit_write will do sync write
21417         $LCTL set_param fail_loc=0x411
21418         # write a full page at the end of file
21419         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21420
21421         $LCTL set_param fail_loc=0
21422         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21423         $LCTL set_param fail_loc=0x411
21424         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21425
21426         # LU-4201
21427         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21428         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21429 }
21430 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21431
21432 test_220() { #LU-325
21433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21434         remote_ost_nodsh && skip "remote OST with nodsh"
21435         remote_mds_nodsh && skip "remote MDS with nodsh"
21436         remote_mgs_nodsh && skip "remote MGS with nodsh"
21437
21438         local OSTIDX=0
21439
21440         # create on MDT0000 so the last_id and next_id are correct
21441         mkdir_on_mdt0 $DIR/$tdir
21442         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21443         OST=${OST%_UUID}
21444
21445         # on the mdt's osc
21446         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21447         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21448                         osp.$mdtosc_proc1.prealloc_last_id)
21449         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21450                         osp.$mdtosc_proc1.prealloc_next_id)
21451
21452         $LFS df -i
21453
21454         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21455         #define OBD_FAIL_OST_ENOINO              0x229
21456         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21457         create_pool $FSNAME.$TESTNAME || return 1
21458         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21459
21460         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21461
21462         MDSOBJS=$((last_id - next_id))
21463         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21464
21465         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21466         echo "OST still has $count kbytes free"
21467
21468         echo "create $MDSOBJS files @next_id..."
21469         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21470
21471         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21472                         osp.$mdtosc_proc1.prealloc_last_id)
21473         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21474                         osp.$mdtosc_proc1.prealloc_next_id)
21475
21476         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21477         $LFS df -i
21478
21479         echo "cleanup..."
21480
21481         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21482         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21483
21484         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21485                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21486         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21487                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21488         echo "unlink $MDSOBJS files @$next_id..."
21489         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21490 }
21491 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21492
21493 test_221() {
21494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21495
21496         dd if=`which date` of=$MOUNT/date oflag=sync
21497         chmod +x $MOUNT/date
21498
21499         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21500         $LCTL set_param fail_loc=0x80001401
21501
21502         $MOUNT/date > /dev/null
21503         rm -f $MOUNT/date
21504 }
21505 run_test 221 "make sure fault and truncate race to not cause OOM"
21506
21507 test_222a () {
21508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21509
21510         rm -rf $DIR/$tdir
21511         test_mkdir $DIR/$tdir
21512         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21513         createmany -o $DIR/$tdir/$tfile 10
21514         cancel_lru_locks mdc
21515         cancel_lru_locks osc
21516         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21517         $LCTL set_param fail_loc=0x31a
21518         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21519         $LCTL set_param fail_loc=0
21520         rm -r $DIR/$tdir
21521 }
21522 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21523
21524 test_222b () {
21525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21526
21527         rm -rf $DIR/$tdir
21528         test_mkdir $DIR/$tdir
21529         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21530         createmany -o $DIR/$tdir/$tfile 10
21531         cancel_lru_locks mdc
21532         cancel_lru_locks osc
21533         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21534         $LCTL set_param fail_loc=0x31a
21535         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21536         $LCTL set_param fail_loc=0
21537 }
21538 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21539
21540 test_223 () {
21541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21542
21543         rm -rf $DIR/$tdir
21544         test_mkdir $DIR/$tdir
21545         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21546         createmany -o $DIR/$tdir/$tfile 10
21547         cancel_lru_locks mdc
21548         cancel_lru_locks osc
21549         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21550         $LCTL set_param fail_loc=0x31b
21551         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21552         $LCTL set_param fail_loc=0
21553         rm -r $DIR/$tdir
21554 }
21555 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21556
21557 test_224a() { # LU-1039, MRP-303
21558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21559         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21560         $LCTL set_param fail_loc=0x508
21561         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21562         $LCTL set_param fail_loc=0
21563         df $DIR
21564 }
21565 run_test 224a "Don't panic on bulk IO failure"
21566
21567 test_224bd_sub() { # LU-1039, MRP-303
21568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21569         local timeout=$1
21570
21571         shift
21572         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21573
21574         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21575
21576         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21577         cancel_lru_locks osc
21578         set_checksums 0
21579         stack_trap "set_checksums $ORIG_CSUM" EXIT
21580         local at_max_saved=0
21581
21582         # adaptive timeouts may prevent seeing the issue
21583         if at_is_enabled; then
21584                 at_max_saved=$(at_max_get mds)
21585                 at_max_set 0 mds client
21586                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21587         fi
21588
21589         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21590         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21591         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21592
21593         do_facet ost1 $LCTL set_param fail_loc=0
21594         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21595         df $DIR
21596 }
21597
21598 test_224b() {
21599         test_224bd_sub 3 error "dd failed"
21600 }
21601 run_test 224b "Don't panic on bulk IO failure"
21602
21603 test_224c() { # LU-6441
21604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21605         remote_mds_nodsh && skip "remote MDS with nodsh"
21606
21607         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21608         save_writethrough $p
21609         set_cache writethrough on
21610
21611         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21612         local at_max=$($LCTL get_param -n at_max)
21613         local timeout=$($LCTL get_param -n timeout)
21614         local test_at="at_max"
21615         local param_at="$FSNAME.sys.at_max"
21616         local test_timeout="timeout"
21617         local param_timeout="$FSNAME.sys.timeout"
21618
21619         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21620
21621         set_persistent_param_and_check client "$test_at" "$param_at" 0
21622         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21623
21624         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21625         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21626         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21627         stack_trap "rm -f $DIR/$tfile"
21628         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21629         sync
21630         do_facet ost1 "$LCTL set_param fail_loc=0"
21631
21632         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21633         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21634                 $timeout
21635
21636         $LCTL set_param -n $pages_per_rpc
21637         restore_lustre_params < $p
21638         rm -f $p
21639 }
21640 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21641
21642 test_224d() { # LU-11169
21643         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21644 }
21645 run_test 224d "Don't corrupt data on bulk IO timeout"
21646
21647 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21648 test_225a () {
21649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21650         if [ -z ${MDSSURVEY} ]; then
21651                 skip_env "mds-survey not found"
21652         fi
21653         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21654                 skip "Need MDS version at least 2.2.51"
21655
21656         local mds=$(facet_host $SINGLEMDS)
21657         local target=$(do_nodes $mds 'lctl dl' |
21658                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21659
21660         local cmd1="file_count=1000 thrhi=4"
21661         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21662         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21663         local cmd="$cmd1 $cmd2 $cmd3"
21664
21665         rm -f ${TMP}/mds_survey*
21666         echo + $cmd
21667         eval $cmd || error "mds-survey with zero-stripe failed"
21668         cat ${TMP}/mds_survey*
21669         rm -f ${TMP}/mds_survey*
21670 }
21671 run_test 225a "Metadata survey sanity with zero-stripe"
21672
21673 test_225b () {
21674         if [ -z ${MDSSURVEY} ]; then
21675                 skip_env "mds-survey not found"
21676         fi
21677         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21678                 skip "Need MDS version at least 2.2.51"
21679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21680         remote_mds_nodsh && skip "remote MDS with nodsh"
21681         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21682                 skip_env "Need to mount OST to test"
21683         fi
21684
21685         local mds=$(facet_host $SINGLEMDS)
21686         local target=$(do_nodes $mds 'lctl dl' |
21687                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21688
21689         local cmd1="file_count=1000 thrhi=4"
21690         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21691         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21692         local cmd="$cmd1 $cmd2 $cmd3"
21693
21694         rm -f ${TMP}/mds_survey*
21695         echo + $cmd
21696         eval $cmd || error "mds-survey with stripe_count failed"
21697         cat ${TMP}/mds_survey*
21698         rm -f ${TMP}/mds_survey*
21699 }
21700 run_test 225b "Metadata survey sanity with stripe_count = 1"
21701
21702 mcreate_path2fid () {
21703         local mode=$1
21704         local major=$2
21705         local minor=$3
21706         local name=$4
21707         local desc=$5
21708         local path=$DIR/$tdir/$name
21709         local fid
21710         local rc
21711         local fid_path
21712
21713         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21714                 error "cannot create $desc"
21715
21716         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21717         rc=$?
21718         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21719
21720         fid_path=$($LFS fid2path $MOUNT $fid)
21721         rc=$?
21722         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21723
21724         [ "$path" == "$fid_path" ] ||
21725                 error "fid2path returned $fid_path, expected $path"
21726
21727         echo "pass with $path and $fid"
21728 }
21729
21730 test_226a () {
21731         rm -rf $DIR/$tdir
21732         mkdir -p $DIR/$tdir
21733
21734         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21735         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21736         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21737         mcreate_path2fid 0040666 0 0 dir "directory"
21738         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21739         mcreate_path2fid 0100666 0 0 file "regular file"
21740         mcreate_path2fid 0120666 0 0 link "symbolic link"
21741         mcreate_path2fid 0140666 0 0 sock "socket"
21742 }
21743 run_test 226a "call path2fid and fid2path on files of all type"
21744
21745 test_226b () {
21746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21747
21748         local MDTIDX=1
21749
21750         rm -rf $DIR/$tdir
21751         mkdir -p $DIR/$tdir
21752         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21753                 error "create remote directory failed"
21754         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21755         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21756                                 "character special file (null)"
21757         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21758                                 "character special file (no device)"
21759         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21760         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21761                                 "block special file (loop)"
21762         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21763         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21764         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21765 }
21766 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21767
21768 test_226c () {
21769         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21770         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21771                 skip "Need MDS version at least 2.13.55"
21772
21773         local submnt=/mnt/submnt
21774         local srcfile=/etc/passwd
21775         local dstfile=$submnt/passwd
21776         local path
21777         local fid
21778
21779         rm -rf $DIR/$tdir
21780         rm -rf $submnt
21781         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21782                 error "create remote directory failed"
21783         mkdir -p $submnt || error "create $submnt failed"
21784         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21785                 error "mount $submnt failed"
21786         stack_trap "umount $submnt" EXIT
21787
21788         cp $srcfile $dstfile
21789         fid=$($LFS path2fid $dstfile)
21790         path=$($LFS fid2path $submnt "$fid")
21791         [ "$path" = "$dstfile" ] ||
21792                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21793 }
21794 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21795
21796 test_226d () {
21797         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21798                 skip "Need client at least version 2.15.57"
21799
21800         # Define First test dataset
21801         local testdirs_01=$DIR/$tdir
21802         local testdata_01=$testdirs_01/${tdir}_01
21803         local testresult_01=${tdir}_01
21804         # Define Second test dataset
21805         local testdirs_02=$DIR/$tdir/$tdir
21806         local testdata_02=$testdirs_02/${tdir}_02
21807         local testresult_02=${tdir}_02
21808         # Define third test dataset (top level)
21809         local testdata_03=$DIR/${tdir}_03
21810         local testresult_03=${tdir}_03
21811
21812         # Create first test dataset
21813         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21814         touch $testdata_01 || error "cannot create file $testdata_01"
21815
21816         # Create second test dataset
21817         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21818         touch $testdata_02 || error "cannot create file $testdata_02"
21819
21820         # Create third test dataset
21821         touch $testdata_03 || error "cannot create file $testdata_03"
21822
21823         local fid01=$($LFS getstripe -F "$testdata_01") ||
21824                 error "getstripe failed on $testdata_01"
21825         local fid02=$($LFS getstripe -F "$testdata_02") ||
21826                 error "getstripe failed on $testdata_01"
21827         local fid03=$($LFS getstripe -F "$testdata_03") ||
21828                 error "getstripe failed on $testdata_03"
21829
21830         # Verify only -n option
21831         local out1=$($LFS fid2path -n $DIR $fid01) ||
21832                 error "fid2path failed on $fid01"
21833         local out2=$($LFS fid2path -n $DIR $fid02) ||
21834                 error "fid2path failed on $fid02"
21835         local out3=$($LFS fid2path -n $DIR $fid03) ||
21836                 error "fid2path failed on $fid03"
21837
21838         [[ "$out1" == "$testresult_01" ]] ||
21839                 error "fid2path failed: Expected $testresult_01 got $out1"
21840         [[ "$out2" == "$testresult_02" ]] ||
21841                 error "fid2path failed: Expected $testresult_02 got $out2"
21842         [[ "$out3" == "$testresult_03" ]] ||
21843                 error "fid2path failed: Expected $testresult_03 got $out3"
21844
21845         # Verify with option -fn together
21846         out1=$($LFS fid2path -fn $DIR $fid01) ||
21847                 error "fid2path -fn failed on $fid01"
21848         out2=$($LFS fid2path -fn $DIR $fid02) ||
21849                 error "fid2path -fn failed on $fid02"
21850         out3=$($LFS fid2path -fn $DIR $fid03) ||
21851                 error "fid2path -fn failed on $fid03"
21852
21853         local tmpout=$(echo $out1 | cut -d" " -f2)
21854         [[ "$tmpout" == "$testresult_01" ]] ||
21855                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21856
21857         tmpout=$(echo $out2 | cut -d" " -f2)
21858         [[ "$tmpout" == "$testresult_02" ]] ||
21859                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21860
21861         tmpout=$(echo $out3 | cut -d" " -f2)
21862         [[ "$tmpout" == "$testresult_03" ]] ||
21863                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21864 }
21865 run_test 226d "verify fid2path with -n and -fn option"
21866
21867 test_226e () {
21868         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21869                 skip "Need client at least version 2.15.56"
21870
21871         # Define filename with 'newline' and a space
21872         local testfile="Test"$'\n'"file 01"
21873         # Define link name with multiple 'newline' and a space
21874         local linkfile="Link"$'\n'"file "$'\n'"01"
21875         # Remove prior hard link
21876         rm -f $DIR/"$linkfile"
21877
21878         # Create file
21879         touch $DIR/"$testfile"
21880         # Create link
21881         ln $DIR/"$testfile" $DIR/"$linkfile"
21882
21883         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21884                 error "getstripe failed on $DIR/$testfile"
21885
21886         # Call with -0 option
21887         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21888                 echo "FILE:" | grep -c "FILE:")
21889
21890         # With -0 option the output should be exactly 2 lines.
21891         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21892 }
21893 run_test 226e "Verify path2fid -0 option with newline and space"
21894
21895 # LU-1299 Executing or running ldd on a truncated executable does not
21896 # cause an out-of-memory condition.
21897 test_227() {
21898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21899         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21900
21901         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21902         chmod +x $MOUNT/date
21903
21904         $MOUNT/date > /dev/null
21905         ldd $MOUNT/date > /dev/null
21906         rm -f $MOUNT/date
21907 }
21908 run_test 227 "running truncated executable does not cause OOM"
21909
21910 # LU-1512 try to reuse idle OI blocks
21911 test_228a() {
21912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21913         remote_mds_nodsh && skip "remote MDS with nodsh"
21914         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21915
21916         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21917         local myDIR=$DIR/$tdir
21918
21919         mkdir -p $myDIR
21920         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21921         $LCTL set_param fail_loc=0x80001002
21922         createmany -o $myDIR/t- 10000
21923         $LCTL set_param fail_loc=0
21924         # The guard is current the largest FID holder
21925         touch $myDIR/guard
21926         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21927                     tr -d '[')
21928         local IDX=$(($SEQ % 64))
21929
21930         do_facet $SINGLEMDS sync
21931         # Make sure journal flushed.
21932         sleep 6
21933         local blk1=$(do_facet $SINGLEMDS \
21934                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21935                      grep Blockcount | awk '{print $4}')
21936
21937         # Remove old files, some OI blocks will become idle.
21938         unlinkmany $myDIR/t- 10000
21939         # Create new files, idle OI blocks should be reused.
21940         createmany -o $myDIR/t- 2000
21941         do_facet $SINGLEMDS sync
21942         # Make sure journal flushed.
21943         sleep 6
21944         local blk2=$(do_facet $SINGLEMDS \
21945                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21946                      grep Blockcount | awk '{print $4}')
21947
21948         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21949 }
21950 run_test 228a "try to reuse idle OI blocks"
21951
21952 test_228b() {
21953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21954         remote_mds_nodsh && skip "remote MDS with nodsh"
21955         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21956
21957         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21958         local myDIR=$DIR/$tdir
21959
21960         mkdir -p $myDIR
21961         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21962         $LCTL set_param fail_loc=0x80001002
21963         createmany -o $myDIR/t- 10000
21964         $LCTL set_param fail_loc=0
21965         # The guard is current the largest FID holder
21966         touch $myDIR/guard
21967         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21968                     tr -d '[')
21969         local IDX=$(($SEQ % 64))
21970
21971         do_facet $SINGLEMDS sync
21972         # Make sure journal flushed.
21973         sleep 6
21974         local blk1=$(do_facet $SINGLEMDS \
21975                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21976                      grep Blockcount | awk '{print $4}')
21977
21978         # Remove old files, some OI blocks will become idle.
21979         unlinkmany $myDIR/t- 10000
21980
21981         # stop the MDT
21982         stop $SINGLEMDS || error "Fail to stop MDT."
21983         # remount the MDT
21984         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21985                 error "Fail to start MDT."
21986
21987         client_up || error "Fail to df."
21988         # Create new files, idle OI blocks should be reused.
21989         createmany -o $myDIR/t- 2000
21990         do_facet $SINGLEMDS sync
21991         # Make sure journal flushed.
21992         sleep 6
21993         local blk2=$(do_facet $SINGLEMDS \
21994                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21995                      grep Blockcount | awk '{print $4}')
21996
21997         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21998 }
21999 run_test 228b "idle OI blocks can be reused after MDT restart"
22000
22001 #LU-1881
22002 test_228c() {
22003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22004         remote_mds_nodsh && skip "remote MDS with nodsh"
22005         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22006
22007         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22008         local myDIR=$DIR/$tdir
22009
22010         mkdir -p $myDIR
22011         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22012         $LCTL set_param fail_loc=0x80001002
22013         # 20000 files can guarantee there are index nodes in the OI file
22014         createmany -o $myDIR/t- 20000
22015         $LCTL set_param fail_loc=0
22016         # The guard is current the largest FID holder
22017         touch $myDIR/guard
22018         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22019                     tr -d '[')
22020         local IDX=$(($SEQ % 64))
22021
22022         do_facet $SINGLEMDS sync
22023         # Make sure journal flushed.
22024         sleep 6
22025         local blk1=$(do_facet $SINGLEMDS \
22026                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22027                      grep Blockcount | awk '{print $4}')
22028
22029         # Remove old files, some OI blocks will become idle.
22030         unlinkmany $myDIR/t- 20000
22031         rm -f $myDIR/guard
22032         # The OI file should become empty now
22033
22034         # Create new files, idle OI blocks should be reused.
22035         createmany -o $myDIR/t- 2000
22036         do_facet $SINGLEMDS sync
22037         # Make sure journal flushed.
22038         sleep 6
22039         local blk2=$(do_facet $SINGLEMDS \
22040                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22041                      grep Blockcount | awk '{print $4}')
22042
22043         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22044 }
22045 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22046
22047 test_229() { # LU-2482, LU-3448
22048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22049         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22050         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22051                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22052
22053         rm -f $DIR/$tfile
22054
22055         # Create a file with a released layout and stripe count 2.
22056         $MULTIOP $DIR/$tfile H2c ||
22057                 error "failed to create file with released layout"
22058
22059         $LFS getstripe -v $DIR/$tfile
22060
22061         local pattern=$($LFS getstripe -L $DIR/$tfile)
22062         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22063
22064         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22065                 error "getstripe"
22066         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22067         stat $DIR/$tfile || error "failed to stat released file"
22068
22069         chown $RUNAS_ID $DIR/$tfile ||
22070                 error "chown $RUNAS_ID $DIR/$tfile failed"
22071
22072         chgrp $RUNAS_ID $DIR/$tfile ||
22073                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22074
22075         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22076         rm $DIR/$tfile || error "failed to remove released file"
22077 }
22078 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22079
22080 test_230a() {
22081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22082         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22083         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22084                 skip "Need MDS version at least 2.11.52"
22085
22086         local MDTIDX=1
22087
22088         test_mkdir $DIR/$tdir
22089         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22090         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22091         [ $mdt_idx -ne 0 ] &&
22092                 error "create local directory on wrong MDT $mdt_idx"
22093
22094         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22095                         error "create remote directory failed"
22096         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22097         [ $mdt_idx -ne $MDTIDX ] &&
22098                 error "create remote directory on wrong MDT $mdt_idx"
22099
22100         createmany -o $DIR/$tdir/test_230/t- 10 ||
22101                 error "create files on remote directory failed"
22102         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22103         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22104         rm -r $DIR/$tdir || error "unlink remote directory failed"
22105 }
22106 run_test 230a "Create remote directory and files under the remote directory"
22107
22108 test_230b() {
22109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22110         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22111         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22112                 skip "Need MDS version at least 2.11.52"
22113
22114         local MDTIDX=1
22115         local mdt_index
22116         local i
22117         local file
22118         local pid
22119         local stripe_count
22120         local migrate_dir=$DIR/$tdir/migrate_dir
22121         local other_dir=$DIR/$tdir/other_dir
22122
22123         test_mkdir $DIR/$tdir
22124         test_mkdir -i0 -c1 $migrate_dir
22125         test_mkdir -i0 -c1 $other_dir
22126         for ((i=0; i<10; i++)); do
22127                 mkdir -p $migrate_dir/dir_${i}
22128                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22129                         error "create files under remote dir failed $i"
22130         done
22131
22132         cp /etc/passwd $migrate_dir/$tfile
22133         cp /etc/passwd $other_dir/$tfile
22134         chattr +SAD $migrate_dir
22135         chattr +SAD $migrate_dir/$tfile
22136
22137         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22138         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22139         local old_dir_mode=$(stat -c%f $migrate_dir)
22140         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22141
22142         mkdir -p $migrate_dir/dir_default_stripe2
22143         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22144         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22145
22146         mkdir -p $other_dir
22147         ln $migrate_dir/$tfile $other_dir/luna
22148         ln $migrate_dir/$tfile $migrate_dir/sofia
22149         ln $other_dir/$tfile $migrate_dir/david
22150         ln -s $migrate_dir/$tfile $other_dir/zachary
22151         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22152         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22153
22154         local len
22155         local lnktgt
22156
22157         # inline symlink
22158         for len in 58 59 60; do
22159                 lnktgt=$(str_repeat 'l' $len)
22160                 touch $migrate_dir/$lnktgt
22161                 ln -s $lnktgt $migrate_dir/${len}char_ln
22162         done
22163
22164         # PATH_MAX
22165         for len in 4094 4095; do
22166                 lnktgt=$(str_repeat 'l' $len)
22167                 ln -s $lnktgt $migrate_dir/${len}char_ln
22168         done
22169
22170         # NAME_MAX
22171         for len in 254 255; do
22172                 touch $migrate_dir/$(str_repeat 'l' $len)
22173         done
22174
22175         $LFS migrate -m $MDTIDX $migrate_dir ||
22176                 error "fails on migrating remote dir to MDT1"
22177
22178         echo "migratate to MDT1, then checking.."
22179         for ((i = 0; i < 10; i++)); do
22180                 for file in $(find $migrate_dir/dir_${i}); do
22181                         mdt_index=$($LFS getstripe -m $file)
22182                         # broken symlink getstripe will fail
22183                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22184                                 error "$file is not on MDT${MDTIDX}"
22185                 done
22186         done
22187
22188         # the multiple link file should still in MDT0
22189         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22190         [ $mdt_index == 0 ] ||
22191                 error "$file is not on MDT${MDTIDX}"
22192
22193         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22194         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22195                 error " expect $old_dir_flag get $new_dir_flag"
22196
22197         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22198         [ "$old_file_flag" = "$new_file_flag" ] ||
22199                 error " expect $old_file_flag get $new_file_flag"
22200
22201         local new_dir_mode=$(stat -c%f $migrate_dir)
22202         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22203                 error "expect mode $old_dir_mode get $new_dir_mode"
22204
22205         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22206         [ "$old_file_mode" = "$new_file_mode" ] ||
22207                 error "expect mode $old_file_mode get $new_file_mode"
22208
22209         diff /etc/passwd $migrate_dir/$tfile ||
22210                 error "$tfile different after migration"
22211
22212         diff /etc/passwd $other_dir/luna ||
22213                 error "luna different after migration"
22214
22215         diff /etc/passwd $migrate_dir/sofia ||
22216                 error "sofia different after migration"
22217
22218         diff /etc/passwd $migrate_dir/david ||
22219                 error "david different after migration"
22220
22221         diff /etc/passwd $other_dir/zachary ||
22222                 error "zachary different after migration"
22223
22224         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22225                 error "${tfile}_ln different after migration"
22226
22227         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22228                 error "${tfile}_ln_other different after migration"
22229
22230         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22231         [ $stripe_count = 2 ] ||
22232                 error "dir strpe_count $d != 2 after migration."
22233
22234         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22235         [ $stripe_count = 2 ] ||
22236                 error "file strpe_count $d != 2 after migration."
22237
22238         #migrate back to MDT0
22239         MDTIDX=0
22240
22241         $LFS migrate -m $MDTIDX $migrate_dir ||
22242                 error "fails on migrating remote dir to MDT0"
22243
22244         echo "migrate back to MDT0, checking.."
22245         for file in $(find $migrate_dir); do
22246                 mdt_index=$($LFS getstripe -m $file)
22247                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22248                         error "$file is not on MDT${MDTIDX}"
22249         done
22250
22251         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22252         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22253                 error " expect $old_dir_flag get $new_dir_flag"
22254
22255         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22256         [ "$old_file_flag" = "$new_file_flag" ] ||
22257                 error " expect $old_file_flag get $new_file_flag"
22258
22259         local new_dir_mode=$(stat -c%f $migrate_dir)
22260         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22261                 error "expect mode $old_dir_mode get $new_dir_mode"
22262
22263         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22264         [ "$old_file_mode" = "$new_file_mode" ] ||
22265                 error "expect mode $old_file_mode get $new_file_mode"
22266
22267         diff /etc/passwd ${migrate_dir}/$tfile ||
22268                 error "$tfile different after migration"
22269
22270         diff /etc/passwd ${other_dir}/luna ||
22271                 error "luna different after migration"
22272
22273         diff /etc/passwd ${migrate_dir}/sofia ||
22274                 error "sofia different after migration"
22275
22276         diff /etc/passwd ${other_dir}/zachary ||
22277                 error "zachary different after migration"
22278
22279         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22280                 error "${tfile}_ln different after migration"
22281
22282         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22283                 error "${tfile}_ln_other different after migration"
22284
22285         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22286         [ $stripe_count = 2 ] ||
22287                 error "dir strpe_count $d != 2 after migration."
22288
22289         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22290         [ $stripe_count = 2 ] ||
22291                 error "file strpe_count $d != 2 after migration."
22292
22293         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22294 }
22295 run_test 230b "migrate directory"
22296
22297 test_230c() {
22298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22300         remote_mds_nodsh && skip "remote MDS with nodsh"
22301         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22302                 skip "Need MDS version at least 2.11.52"
22303
22304         local MDTIDX=1
22305         local total=3
22306         local mdt_index
22307         local file
22308         local migrate_dir=$DIR/$tdir/migrate_dir
22309
22310         #If migrating directory fails in the middle, all entries of
22311         #the directory is still accessiable.
22312         test_mkdir $DIR/$tdir
22313         test_mkdir -i0 -c1 $migrate_dir
22314         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22315         stat $migrate_dir
22316         createmany -o $migrate_dir/f $total ||
22317                 error "create files under ${migrate_dir} failed"
22318
22319         # fail after migrating top dir, and this will fail only once, so the
22320         # first sub file migration will fail (currently f3), others succeed.
22321         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22322         do_facet mds1 lctl set_param fail_loc=0x1801
22323         local t=$(ls $migrate_dir | wc -l)
22324         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22325                 error "migrate should fail"
22326         local u=$(ls $migrate_dir | wc -l)
22327         [ "$u" == "$t" ] || error "$u != $t during migration"
22328
22329         # add new dir/file should succeed
22330         mkdir $migrate_dir/dir ||
22331                 error "mkdir failed under migrating directory"
22332         touch $migrate_dir/file ||
22333                 error "create file failed under migrating directory"
22334
22335         # add file with existing name should fail
22336         for file in $migrate_dir/f*; do
22337                 stat $file > /dev/null || error "stat $file failed"
22338                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22339                         error "open(O_CREAT|O_EXCL) $file should fail"
22340                 $MULTIOP $file m && error "create $file should fail"
22341                 touch $DIR/$tdir/remote_dir/$tfile ||
22342                         error "touch $tfile failed"
22343                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22344                         error "link $file should fail"
22345                 mdt_index=$($LFS getstripe -m $file)
22346                 if [ $mdt_index == 0 ]; then
22347                         # file failed to migrate is not allowed to rename to
22348                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22349                                 error "rename to $file should fail"
22350                 else
22351                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22352                                 error "rename to $file failed"
22353                 fi
22354                 echo hello >> $file || error "write $file failed"
22355         done
22356
22357         # resume migration with different options should fail
22358         $LFS migrate -m 0 $migrate_dir &&
22359                 error "migrate -m 0 $migrate_dir should fail"
22360
22361         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22362                 error "migrate -c 2 $migrate_dir should fail"
22363
22364         # resume migration should succeed
22365         $LFS migrate -m $MDTIDX $migrate_dir ||
22366                 error "migrate $migrate_dir failed"
22367
22368         echo "Finish migration, then checking.."
22369         for file in $(find $migrate_dir); do
22370                 mdt_index=$($LFS getstripe -m $file)
22371                 [ $mdt_index == $MDTIDX ] ||
22372                         error "$file is not on MDT${MDTIDX}"
22373         done
22374
22375         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22376 }
22377 run_test 230c "check directory accessiblity if migration failed"
22378
22379 test_230d() {
22380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22382         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22383                 skip "Need MDS version at least 2.11.52"
22384         # LU-11235
22385         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22386
22387         local migrate_dir=$DIR/$tdir/migrate_dir
22388         local old_index
22389         local new_index
22390         local old_count
22391         local new_count
22392         local new_hash
22393         local mdt_index
22394         local i
22395         local j
22396
22397         old_index=$((RANDOM % MDSCOUNT))
22398         old_count=$((MDSCOUNT - old_index))
22399         new_index=$((RANDOM % MDSCOUNT))
22400         new_count=$((MDSCOUNT - new_index))
22401         new_hash=1 # for all_char
22402
22403         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22404         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22405
22406         test_mkdir $DIR/$tdir
22407         test_mkdir -i $old_index -c $old_count $migrate_dir
22408
22409         for ((i=0; i<100; i++)); do
22410                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22411                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22412                         error "create files under remote dir failed $i"
22413         done
22414
22415         echo -n "Migrate from MDT$old_index "
22416         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22417         echo -n "to MDT$new_index"
22418         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22419         echo
22420
22421         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22422         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22423                 error "migrate remote dir error"
22424
22425         echo "Finish migration, then checking.."
22426         for file in $(find $migrate_dir -maxdepth 1); do
22427                 mdt_index=$($LFS getstripe -m $file)
22428                 if [ $mdt_index -lt $new_index ] ||
22429                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22430                         error "$file is on MDT$mdt_index"
22431                 fi
22432         done
22433
22434         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22435 }
22436 run_test 230d "check migrate big directory"
22437
22438 test_230e() {
22439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22441         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22442                 skip "Need MDS version at least 2.11.52"
22443
22444         local i
22445         local j
22446         local a_fid
22447         local b_fid
22448
22449         mkdir_on_mdt0 $DIR/$tdir
22450         mkdir $DIR/$tdir/migrate_dir
22451         mkdir $DIR/$tdir/other_dir
22452         touch $DIR/$tdir/migrate_dir/a
22453         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22454         ls $DIR/$tdir/other_dir
22455
22456         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22457                 error "migrate dir fails"
22458
22459         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22460         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22461
22462         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22463         [ $mdt_index == 0 ] || error "a is not on MDT0"
22464
22465         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22466                 error "migrate dir fails"
22467
22468         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22469         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22470
22471         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22472         [ $mdt_index == 1 ] || error "a is not on MDT1"
22473
22474         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22475         [ $mdt_index == 1 ] || error "b is not on MDT1"
22476
22477         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22478         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22479
22480         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22481
22482         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22483 }
22484 run_test 230e "migrate mulitple local link files"
22485
22486 test_230f() {
22487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22488         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22489         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22490                 skip "Need MDS version at least 2.11.52"
22491
22492         local a_fid
22493         local ln_fid
22494
22495         mkdir -p $DIR/$tdir
22496         mkdir $DIR/$tdir/migrate_dir
22497         $LFS mkdir -i1 $DIR/$tdir/other_dir
22498         touch $DIR/$tdir/migrate_dir/a
22499         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22500         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22501         ls $DIR/$tdir/other_dir
22502
22503         # a should be migrated to MDT1, since no other links on MDT0
22504         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22505                 error "#1 migrate dir fails"
22506         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22507         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22508         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22509         [ $mdt_index == 1 ] || error "a is not on MDT1"
22510
22511         # a should stay on MDT1, because it is a mulitple link file
22512         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22513                 error "#2 migrate dir fails"
22514         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22515         [ $mdt_index == 1 ] || error "a is not on MDT1"
22516
22517         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22518                 error "#3 migrate dir fails"
22519
22520         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22521         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22522         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22523
22524         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22525         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22526
22527         # a should be migrated to MDT0, since no other links on MDT1
22528         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22529                 error "#4 migrate dir fails"
22530         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22531         [ $mdt_index == 0 ] || error "a is not on MDT0"
22532
22533         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22534 }
22535 run_test 230f "migrate mulitple remote link files"
22536
22537 test_230g() {
22538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22539         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22540         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22541                 skip "Need MDS version at least 2.11.52"
22542
22543         mkdir -p $DIR/$tdir/migrate_dir
22544
22545         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22546                 error "migrating dir to non-exist MDT succeeds"
22547         true
22548 }
22549 run_test 230g "migrate dir to non-exist MDT"
22550
22551 test_230h() {
22552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22554         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22555                 skip "Need MDS version at least 2.11.52"
22556
22557         local mdt_index
22558
22559         mkdir -p $DIR/$tdir/migrate_dir
22560
22561         $LFS migrate -m1 $DIR &&
22562                 error "migrating mountpoint1 should fail"
22563
22564         $LFS migrate -m1 $DIR/$tdir/.. &&
22565                 error "migrating mountpoint2 should fail"
22566
22567         # same as mv
22568         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22569                 error "migrating $tdir/migrate_dir/.. should fail"
22570
22571         true
22572 }
22573 run_test 230h "migrate .. and root"
22574
22575 test_230i() {
22576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22578         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22579                 skip "Need MDS version at least 2.11.52"
22580
22581         mkdir -p $DIR/$tdir/migrate_dir
22582
22583         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22584                 error "migration fails with a tailing slash"
22585
22586         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22587                 error "migration fails with two tailing slashes"
22588 }
22589 run_test 230i "lfs migrate -m tolerates trailing slashes"
22590
22591 test_230j() {
22592         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22593         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22594                 skip "Need MDS version at least 2.11.52"
22595
22596         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22597         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22598                 error "create $tfile failed"
22599         cat /etc/passwd > $DIR/$tdir/$tfile
22600
22601         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22602
22603         cmp /etc/passwd $DIR/$tdir/$tfile ||
22604                 error "DoM file mismatch after migration"
22605 }
22606 run_test 230j "DoM file data not changed after dir migration"
22607
22608 test_230k() {
22609         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22610         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22611                 skip "Need MDS version at least 2.11.56"
22612
22613         local total=20
22614         local files_on_starting_mdt=0
22615
22616         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22617         $LFS getdirstripe $DIR/$tdir
22618         for i in $(seq $total); do
22619                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22620                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22621                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22622         done
22623
22624         echo "$files_on_starting_mdt files on MDT0"
22625
22626         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22627         $LFS getdirstripe $DIR/$tdir
22628
22629         files_on_starting_mdt=0
22630         for i in $(seq $total); do
22631                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22632                         error "file $tfile.$i mismatch after migration"
22633                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22634                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22635         done
22636
22637         echo "$files_on_starting_mdt files on MDT1 after migration"
22638         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22639
22640         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22641         $LFS getdirstripe $DIR/$tdir
22642
22643         files_on_starting_mdt=0
22644         for i in $(seq $total); do
22645                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22646                         error "file $tfile.$i mismatch after 2nd migration"
22647                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22648                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22649         done
22650
22651         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22652         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22653
22654         true
22655 }
22656 run_test 230k "file data not changed after dir migration"
22657
22658 test_230l() {
22659         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22660         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22661                 skip "Need MDS version at least 2.11.56"
22662
22663         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22664         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22665                 error "create files under remote dir failed $i"
22666         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22667 }
22668 run_test 230l "readdir between MDTs won't crash"
22669
22670 test_230m() {
22671         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22672         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22673                 skip "Need MDS version at least 2.11.56"
22674
22675         local MDTIDX=1
22676         local mig_dir=$DIR/$tdir/migrate_dir
22677         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22678         local shortstr="b"
22679         local val
22680
22681         echo "Creating files and dirs with xattrs"
22682         test_mkdir $DIR/$tdir
22683         test_mkdir -i0 -c1 $mig_dir
22684         mkdir $mig_dir/dir
22685         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22686                 error "cannot set xattr attr1 on dir"
22687         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22688                 error "cannot set xattr attr2 on dir"
22689         touch $mig_dir/dir/f0
22690         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22691                 error "cannot set xattr attr1 on file"
22692         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22693                 error "cannot set xattr attr2 on file"
22694         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22695         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22696         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22697         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22698         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22699         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22700         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22701         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22702         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22703
22704         echo "Migrating to MDT1"
22705         $LFS migrate -m $MDTIDX $mig_dir ||
22706                 error "fails on migrating dir to MDT1"
22707
22708         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22709         echo "Checking xattrs"
22710         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22711         [ "$val" = $longstr ] ||
22712                 error "expecting xattr1 $longstr on dir, found $val"
22713         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22714         [ "$val" = $shortstr ] ||
22715                 error "expecting xattr2 $shortstr on dir, found $val"
22716         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22717         [ "$val" = $longstr ] ||
22718                 error "expecting xattr1 $longstr on file, found $val"
22719         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22720         [ "$val" = $shortstr ] ||
22721                 error "expecting xattr2 $shortstr on file, found $val"
22722 }
22723 run_test 230m "xattrs not changed after dir migration"
22724
22725 test_230n() {
22726         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22727         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22728                 skip "Need MDS version at least 2.13.53"
22729
22730         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22731         cat /etc/hosts > $DIR/$tdir/$tfile
22732         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22733         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22734
22735         cmp /etc/hosts $DIR/$tdir/$tfile ||
22736                 error "File data mismatch after migration"
22737 }
22738 run_test 230n "Dir migration with mirrored file"
22739
22740 test_230o() {
22741         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22742         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22743                 skip "Need MDS version at least 2.13.52"
22744
22745         local mdts=$(comma_list $(mdts_nodes))
22746         local timeout=100
22747         local restripe_status
22748         local delta
22749         local i
22750
22751         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22752
22753         # in case "crush" hash type is not set
22754         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22755
22756         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22757                            mdt.*MDT0000.enable_dir_restripe)
22758         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22759         stack_trap "do_nodes $mdts $LCTL set_param \
22760                     mdt.*.enable_dir_restripe=$restripe_status"
22761
22762         mkdir $DIR/$tdir
22763         createmany -m $DIR/$tdir/f 100 ||
22764                 error "create files under remote dir failed $i"
22765         createmany -d $DIR/$tdir/d 100 ||
22766                 error "create dirs under remote dir failed $i"
22767
22768         for i in $(seq 2 $MDSCOUNT); do
22769                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22770                 $LFS setdirstripe -c $i $DIR/$tdir ||
22771                         error "split -c $i $tdir failed"
22772                 wait_update $HOSTNAME \
22773                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22774                         error "dir split not finished"
22775                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22776                         awk '/migrate/ {sum += $2} END { print sum }')
22777                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22778                 # delta is around total_files/stripe_count
22779                 (( $delta < 200 / (i - 1) + 4 )) ||
22780                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22781         done
22782 }
22783 run_test 230o "dir split"
22784
22785 test_230p() {
22786         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22787         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22788                 skip "Need MDS version at least 2.13.52"
22789
22790         local mdts=$(comma_list $(mdts_nodes))
22791         local timeout=100
22792         local restripe_status
22793         local delta
22794         local c
22795
22796         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22797
22798         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22799
22800         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22801                            mdt.*MDT0000.enable_dir_restripe)
22802         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22803         stack_trap "do_nodes $mdts $LCTL set_param \
22804                     mdt.*.enable_dir_restripe=$restripe_status"
22805
22806         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22807         createmany -m $DIR/$tdir/f 100 ||
22808                 error "create files under remote dir failed"
22809         createmany -d $DIR/$tdir/d 100 ||
22810                 error "create dirs under remote dir failed"
22811
22812         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22813                 local mdt_hash="crush"
22814
22815                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22816                 $LFS setdirstripe -c $c $DIR/$tdir ||
22817                         error "split -c $c $tdir failed"
22818                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22819                         mdt_hash="$mdt_hash,fixed"
22820                 elif [ $c -eq 1 ]; then
22821                         mdt_hash="none"
22822                 fi
22823                 wait_update $HOSTNAME \
22824                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22825                         error "dir merge not finished"
22826                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22827                         awk '/migrate/ {sum += $2} END { print sum }')
22828                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22829                 # delta is around total_files/stripe_count
22830                 (( delta < 200 / c + 4 )) ||
22831                         error "$delta files migrated >= $((200 / c + 4))"
22832         done
22833 }
22834 run_test 230p "dir merge"
22835
22836 test_230q() {
22837         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22838         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22839                 skip "Need MDS version at least 2.13.52"
22840
22841         local mdts=$(comma_list $(mdts_nodes))
22842         local saved_threshold=$(do_facet mds1 \
22843                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22844         local saved_delta=$(do_facet mds1 \
22845                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22846         local threshold=100
22847         local delta=2
22848         local total=0
22849         local stripe_count=0
22850         local stripe_index
22851         local nr_files
22852         local create
22853
22854         # test with fewer files on ZFS
22855         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22856
22857         stack_trap "do_nodes $mdts $LCTL set_param \
22858                     mdt.*.dir_split_count=$saved_threshold"
22859         stack_trap "do_nodes $mdts $LCTL set_param \
22860                     mdt.*.dir_split_delta=$saved_delta"
22861         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22862         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22863         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22864         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22865         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22866         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22867
22868         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22869         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22870
22871         create=$((threshold * 3 / 2))
22872         while [ $stripe_count -lt $MDSCOUNT ]; do
22873                 createmany -m $DIR/$tdir/f $total $create ||
22874                         error "create sub files failed"
22875                 stat $DIR/$tdir > /dev/null
22876                 total=$((total + create))
22877                 stripe_count=$((stripe_count + delta))
22878                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22879
22880                 wait_update $HOSTNAME \
22881                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22882                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22883
22884                 wait_update $HOSTNAME \
22885                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22886                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22887
22888                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22889                 echo "$nr_files/$total files on MDT$stripe_index after split"
22890                 # allow 10% margin of imbalance with crush hash
22891                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22892                         error "$nr_files files on MDT$stripe_index after split"
22893
22894                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22895                 [ $nr_files -eq $total ] ||
22896                         error "total sub files $nr_files != $total"
22897         done
22898
22899         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22900
22901         echo "fixed layout directory won't auto split"
22902         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22903         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22904                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22905         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22906                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22907 }
22908 run_test 230q "dir auto split"
22909
22910 test_230r() {
22911         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22912         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22913         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22914                 skip "Need MDS version at least 2.13.54"
22915
22916         # maximum amount of local locks:
22917         # parent striped dir - 2 locks
22918         # new stripe in parent to migrate to - 1 lock
22919         # source and target - 2 locks
22920         # Total 5 locks for regular file
22921         mkdir -p $DIR/$tdir
22922         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22923         touch $DIR/$tdir/dir1/eee
22924
22925         # create 4 hardlink for 4 more locks
22926         # Total: 9 locks > RS_MAX_LOCKS (8)
22927         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22928         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22929         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22930         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22931         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22932         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22933         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22934         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22935
22936         cancel_lru_locks mdc
22937
22938         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22939                 error "migrate dir fails"
22940
22941         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22942 }
22943 run_test 230r "migrate with too many local locks"
22944
22945 test_230s() {
22946         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22947                 skip "Need MDS version at least 2.14.52"
22948
22949         local mdts=$(comma_list $(mdts_nodes))
22950         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22951                                 mdt.*MDT0000.enable_dir_restripe)
22952
22953         stack_trap "do_nodes $mdts $LCTL set_param \
22954                     mdt.*.enable_dir_restripe=$restripe_status"
22955
22956         local st
22957         for st in 0 1; do
22958                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22959                 test_mkdir $DIR/$tdir
22960                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22961                         error "$LFS mkdir should return EEXIST if target exists"
22962                 rmdir $DIR/$tdir
22963         done
22964 }
22965 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22966
22967 test_230t()
22968 {
22969         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22970         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22971                 skip "Need MDS version at least 2.14.50"
22972
22973         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22974         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22975         $LFS project -p 1 -s $DIR/$tdir ||
22976                 error "set $tdir project id failed"
22977         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22978                 error "set subdir project id failed"
22979         local pbefore="$($LFS project -d $DIR/$tdir)"
22980         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22981         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22982
22983         local pafter="$($LFS project -d $DIR/$tdir)"
22984         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22985         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22986         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22987
22988         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22989                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22990
22991         # check rename works, even if source parent projid differs (LU-17016)
22992         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22993         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22994
22995         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22996         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22997                 error "subdir failed rename for different source parent projid"
22998         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22999
23000         [[ "$fid_before" == "$fid_after" ]] ||
23001                 error "fid before '$fid_before' != after '$fid_after'"
23002 }
23003 run_test 230t "migrate directory with project ID set"
23004
23005 test_230u()
23006 {
23007         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23008         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23009                 skip "Need MDS version at least 2.14.53"
23010
23011         local count
23012
23013         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23014         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23015         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
23016         for i in $(seq 0 $((MDSCOUNT - 1))); do
23017                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23018                 echo "$count dirs migrated to MDT$i"
23019         done
23020         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23021         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
23022 }
23023 run_test 230u "migrate directory by QOS"
23024
23025 test_230v()
23026 {
23027         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23028         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23029                 skip "Need MDS version at least 2.14.53"
23030
23031         local count
23032
23033         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23034         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23035         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23036         for i in $(seq 0 $((MDSCOUNT - 1))); do
23037                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23038                 echo "$count subdirs migrated to MDT$i"
23039                 (( i == 3 )) && (( count > 0 )) &&
23040                         error "subdir shouldn't be migrated to MDT3"
23041         done
23042         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23043         (( count == 3 )) || error "dirs migrated to $count MDTs"
23044 }
23045 run_test 230v "subdir migrated to the MDT where its parent is located"
23046
23047 test_230w() {
23048         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23049         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23050                 skip "Need MDS version at least 2.15.0"
23051
23052         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23053         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23054         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23055
23056         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23057                 error "migrate failed"
23058
23059         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23060                 error "$tdir stripe count mismatch"
23061
23062         for i in $(seq 0 9); do
23063                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23064                         error "d$i is striped"
23065         done
23066 }
23067 run_test 230w "non-recursive mode dir migration"
23068
23069 test_230x() {
23070         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23071         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23072                 skip "Need MDS version at least 2.15.0"
23073
23074         mkdir -p $DIR/$tdir || error "mkdir failed"
23075         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23076
23077         local mdt_name=$(mdtname_from_index 0)
23078         local low=$(do_facet mds2 $LCTL get_param -n \
23079                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23080         local high=$(do_facet mds2 $LCTL get_param -n \
23081                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23082         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23083         local maxage=$(do_facet mds2 $LCTL get_param -n \
23084                 osp.*$mdt_name-osp-MDT0001.maxage)
23085
23086         stack_trap "do_facet mds2 $LCTL set_param -n \
23087                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23088                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23089         stack_trap "do_facet mds2 $LCTL set_param -n \
23090                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23091
23092         do_facet mds2 $LCTL set_param -n \
23093                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23094         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23095         sleep 4
23096         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23097                 error "migrate $tdir should fail"
23098
23099         do_facet mds2 $LCTL set_param -n \
23100                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23101         do_facet mds2 $LCTL set_param -n \
23102                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23103         sleep 4
23104         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23105                 error "migrate failed"
23106         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23107                 error "$tdir stripe count mismatch"
23108 }
23109 run_test 230x "dir migration check space"
23110
23111 test_230y() {
23112         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23113         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23114                 skip "Need MDS version at least 2.15.55.45"
23115
23116         local pid
23117
23118         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23119         $LFS getdirstripe $DIR/$tdir
23120         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23121         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23122         pid=$!
23123         sleep 1
23124
23125         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23126         do_facet mds2 lctl set_param fail_loc=0x1802
23127
23128         wait $pid
23129         do_facet mds2 lctl set_param fail_loc=0
23130         $LFS getdirstripe $DIR/$tdir
23131         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23132         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23133 }
23134 run_test 230y "unlink dir with bad hash type"
23135
23136 test_230z() {
23137         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23138         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23139                 skip "Need MDS version at least 2.15.55.45"
23140
23141         local pid
23142
23143         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23144         $LFS getdirstripe $DIR/$tdir
23145         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23146         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23147         pid=$!
23148         sleep 1
23149
23150         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23151         do_facet mds2 lctl set_param fail_loc=0x1802
23152
23153         wait $pid
23154         do_facet mds2 lctl set_param fail_loc=0
23155         $LFS getdirstripe $DIR/$tdir
23156
23157         # resume migration
23158         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23159                 error "resume migration failed"
23160         $LFS getdirstripe $DIR/$tdir
23161         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23162                 error "migration is not finished"
23163 }
23164 run_test 230z "resume dir migration with bad hash type"
23165
23166 test_231a()
23167 {
23168         # For simplicity this test assumes that max_pages_per_rpc
23169         # is the same across all OSCs
23170         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23171         local bulk_size=$((max_pages * PAGE_SIZE))
23172         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23173                                        head -n 1)
23174
23175         mkdir -p $DIR/$tdir
23176         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23177                 error "failed to set stripe with -S ${brw_size}M option"
23178         stack_trap "rm -rf $DIR/$tdir"
23179
23180         # clear the OSC stats
23181         $LCTL set_param osc.*.stats=0 &>/dev/null
23182         stop_writeback
23183
23184         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23185         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23186                 oflag=direct &>/dev/null || error "dd failed"
23187
23188         sync; sleep 1; sync # just to be safe
23189         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23190         if [ x$nrpcs != "x1" ]; then
23191                 $LCTL get_param osc.*.stats
23192                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23193         fi
23194
23195         start_writeback
23196         # Drop the OSC cache, otherwise we will read from it
23197         cancel_lru_locks osc
23198
23199         # clear the OSC stats
23200         $LCTL set_param osc.*.stats=0 &>/dev/null
23201
23202         # Client reads $bulk_size.
23203         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23204                 iflag=direct &>/dev/null || error "dd failed"
23205
23206         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23207         if [ x$nrpcs != "x1" ]; then
23208                 $LCTL get_param osc.*.stats
23209                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23210         fi
23211 }
23212 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23213
23214 test_231b() {
23215         mkdir -p $DIR/$tdir
23216         stack_trap "rm -rf $DIR/$tdir"
23217         local i
23218         for i in {0..1023}; do
23219                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23220                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23221                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23222         done
23223         sync
23224 }
23225 run_test 231b "must not assert on fully utilized OST request buffer"
23226
23227 test_232a() {
23228         mkdir -p $DIR/$tdir
23229         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23230
23231         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23232         do_facet ost1 $LCTL set_param fail_loc=0x31c
23233
23234         # ignore dd failure
23235         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23236         stack_trap "rm -f $DIR/$tdir/$tfile"
23237
23238         do_facet ost1 $LCTL set_param fail_loc=0
23239         umount_client $MOUNT || error "umount failed"
23240         mount_client $MOUNT || error "mount failed"
23241         stop ost1 || error "cannot stop ost1"
23242         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23243 }
23244 run_test 232a "failed lock should not block umount"
23245
23246 test_232b() {
23247         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23248                 skip "Need MDS version at least 2.10.58"
23249
23250         mkdir -p $DIR/$tdir
23251         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23252         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23253         stack_trap "rm -f $DIR/$tdir/$tfile"
23254         sync
23255         cancel_lru_locks osc
23256
23257         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23258         do_facet ost1 $LCTL set_param fail_loc=0x31c
23259
23260         # ignore failure
23261         $LFS data_version $DIR/$tdir/$tfile || true
23262
23263         do_facet ost1 $LCTL set_param fail_loc=0
23264         umount_client $MOUNT || error "umount failed"
23265         mount_client $MOUNT || error "mount failed"
23266         stop ost1 || error "cannot stop ost1"
23267         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23268 }
23269 run_test 232b "failed data version lock should not block umount"
23270
23271 test_233a() {
23272         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23273                 skip "Need MDS version at least 2.3.64"
23274         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23275
23276         local fid=$($LFS path2fid $MOUNT)
23277
23278         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23279                 error "cannot access $MOUNT using its FID '$fid'"
23280 }
23281 run_test 233a "checking that OBF of the FS root succeeds"
23282
23283 test_233b() {
23284         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23285                 skip "Need MDS version at least 2.5.90"
23286         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23287
23288         local fid=$($LFS path2fid $MOUNT/.lustre)
23289
23290         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23291                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23292
23293         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23294         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23295                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23296 }
23297 run_test 233b "checking that OBF of the FS .lustre succeeds"
23298
23299 test_234() {
23300         local p="$TMP/sanityN-$TESTNAME.parameters"
23301         save_lustre_params client "llite.*.xattr_cache" > $p
23302         lctl set_param llite.*.xattr_cache 1 ||
23303                 skip_env "xattr cache is not supported"
23304
23305         mkdir -p $DIR/$tdir || error "mkdir failed"
23306         touch $DIR/$tdir/$tfile || error "touch failed"
23307         # OBD_FAIL_LLITE_XATTR_ENOMEM
23308         $LCTL set_param fail_loc=0x1405
23309         getfattr -n user.attr $DIR/$tdir/$tfile &&
23310                 error "getfattr should have failed with ENOMEM"
23311         $LCTL set_param fail_loc=0x0
23312         rm -rf $DIR/$tdir
23313
23314         restore_lustre_params < $p
23315         rm -f $p
23316 }
23317 run_test 234 "xattr cache should not crash on ENOMEM"
23318
23319 test_235() {
23320         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23321                 skip "Need MDS version at least 2.4.52"
23322
23323         flock_deadlock $DIR/$tfile
23324         local RC=$?
23325         case $RC in
23326                 0)
23327                 ;;
23328                 124) error "process hangs on a deadlock"
23329                 ;;
23330                 *) error "error executing flock_deadlock $DIR/$tfile"
23331                 ;;
23332         esac
23333 }
23334 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23335
23336 #LU-2935
23337 test_236() {
23338         check_swap_layouts_support
23339
23340         local ref1=/etc/passwd
23341         local ref2=/etc/group
23342         local file1=$DIR/$tdir/f1
23343         local file2=$DIR/$tdir/f2
23344
23345         test_mkdir -c1 $DIR/$tdir
23346         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23347         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23348         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23349         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23350         local fd=$(free_fd)
23351         local cmd="exec $fd<>$file2"
23352         eval $cmd
23353         rm $file2
23354         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23355                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23356         cmd="exec $fd>&-"
23357         eval $cmd
23358         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23359
23360         #cleanup
23361         rm -rf $DIR/$tdir
23362 }
23363 run_test 236 "Layout swap on open unlinked file"
23364
23365 # LU-4659 linkea consistency
23366 test_238() {
23367         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23368                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23369                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23370                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23371
23372         touch $DIR/$tfile
23373         ln $DIR/$tfile $DIR/$tfile.lnk
23374         touch $DIR/$tfile.new
23375         mv $DIR/$tfile.new $DIR/$tfile
23376         local fid1=$($LFS path2fid $DIR/$tfile)
23377         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23378         local path1=$($LFS fid2path $FSNAME "$fid1")
23379         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23380         local path2=$($LFS fid2path $FSNAME "$fid2")
23381         [ $tfile.lnk == $path2 ] ||
23382                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23383         rm -f $DIR/$tfile*
23384 }
23385 run_test 238 "Verify linkea consistency"
23386
23387 test_239A() { # was test_239
23388         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23389                 skip "Need MDS version at least 2.5.60"
23390
23391         local list=$(comma_list $(mdts_nodes))
23392
23393         mkdir -p $DIR/$tdir
23394         createmany -o $DIR/$tdir/f- 5000
23395         unlinkmany $DIR/$tdir/f- 5000
23396         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23397                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23398         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23399                         osp.*MDT*.sync_in_flight" | calc_sum)
23400         [ "$changes" -eq 0 ] || error "$changes not synced"
23401 }
23402 run_test 239A "osp_sync test"
23403
23404 test_239a() { #LU-5297
23405         remote_mds_nodsh && skip "remote MDS with nodsh"
23406
23407         touch $DIR/$tfile
23408         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23409         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23410         chgrp $RUNAS_GID $DIR/$tfile
23411         wait_delete_completed
23412 }
23413 run_test 239a "process invalid osp sync record correctly"
23414
23415 test_239b() { #LU-5297
23416         remote_mds_nodsh && skip "remote MDS with nodsh"
23417
23418         touch $DIR/$tfile1
23419         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23420         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23421         chgrp $RUNAS_GID $DIR/$tfile1
23422         wait_delete_completed
23423         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23424         touch $DIR/$tfile2
23425         chgrp $RUNAS_GID $DIR/$tfile2
23426         wait_delete_completed
23427 }
23428 run_test 239b "process osp sync record with ENOMEM error correctly"
23429
23430 test_240() {
23431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23432         remote_mds_nodsh && skip "remote MDS with nodsh"
23433
23434         mkdir -p $DIR/$tdir
23435
23436         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23437                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23438         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23439                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23440
23441         umount_client $MOUNT || error "umount failed"
23442         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23443         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23444         mount_client $MOUNT || error "failed to mount client"
23445
23446         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23447         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23448 }
23449 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23450
23451 test_241_bio() {
23452         local count=$1
23453         local bsize=$2
23454
23455         for LOOP in $(seq $count); do
23456                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23457                 cancel_lru_locks $OSC || true
23458         done
23459 }
23460
23461 test_241_dio() {
23462         local count=$1
23463         local bsize=$2
23464
23465         for LOOP in $(seq $1); do
23466                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23467                         2>/dev/null
23468         done
23469 }
23470
23471 test_241a() { # was test_241
23472         local bsize=$PAGE_SIZE
23473
23474         (( bsize < 40960 )) && bsize=40960
23475         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23476         ls -la $DIR/$tfile
23477         cancel_lru_locks $OSC
23478         test_241_bio 1000 $bsize &
23479         PID=$!
23480         test_241_dio 1000 $bsize
23481         wait $PID
23482 }
23483 run_test 241a "bio vs dio"
23484
23485 test_241b() {
23486         local bsize=$PAGE_SIZE
23487
23488         (( bsize < 40960 )) && bsize=40960
23489         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23490         ls -la $DIR/$tfile
23491         test_241_dio 1000 $bsize &
23492         PID=$!
23493         test_241_dio 1000 $bsize
23494         wait $PID
23495 }
23496 run_test 241b "dio vs dio"
23497
23498 test_242() {
23499         remote_mds_nodsh && skip "remote MDS with nodsh"
23500
23501         mkdir_on_mdt0 $DIR/$tdir
23502         touch $DIR/$tdir/$tfile
23503
23504         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23505         do_facet mds1 lctl set_param fail_loc=0x105
23506         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23507
23508         do_facet mds1 lctl set_param fail_loc=0
23509         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23510 }
23511 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23512
23513 test_243()
23514 {
23515         test_mkdir $DIR/$tdir
23516         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23517 }
23518 run_test 243 "various group lock tests"
23519
23520 test_244a()
23521 {
23522         test_mkdir $DIR/$tdir
23523         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23524         sendfile_grouplock $DIR/$tdir/$tfile || \
23525                 error "sendfile+grouplock failed"
23526         rm -rf $DIR/$tdir
23527 }
23528 run_test 244a "sendfile with group lock tests"
23529
23530 test_244b()
23531 {
23532         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23533
23534         local threads=50
23535         local size=$((1024*1024))
23536
23537         test_mkdir $DIR/$tdir
23538         for i in $(seq 1 $threads); do
23539                 local file=$DIR/$tdir/file_$((i / 10))
23540                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23541                 local pids[$i]=$!
23542         done
23543         for i in $(seq 1 $threads); do
23544                 wait ${pids[$i]}
23545         done
23546 }
23547 run_test 244b "multi-threaded write with group lock"
23548
23549 test_245a() {
23550         local flagname="multi_mod_rpcs"
23551         local connect_data_name="max_mod_rpcs"
23552         local out
23553
23554         # check if multiple modify RPCs flag is set
23555         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23556                 grep "connect_flags:")
23557         echo "$out"
23558
23559         echo "$out" | grep -qw $flagname
23560         if [ $? -ne 0 ]; then
23561                 echo "connect flag $flagname is not set"
23562                 return
23563         fi
23564
23565         # check if multiple modify RPCs data is set
23566         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23567         echo "$out"
23568
23569         echo "$out" | grep -qw $connect_data_name ||
23570                 error "import should have connect data $connect_data_name"
23571 }
23572 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23573
23574 test_245b() {
23575         local flagname="multi_mod_rpcs"
23576         local connect_data_name="max_mod_rpcs"
23577         local out
23578
23579         remote_mds_nodsh && skip "remote MDS with nodsh"
23580         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23581
23582         # check if multiple modify RPCs flag is set
23583         out=$(do_facet mds1 \
23584               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23585               grep "connect_flags:")
23586         echo "$out"
23587
23588         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23589
23590         # check if multiple modify RPCs data is set
23591         out=$(do_facet mds1 \
23592               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23593
23594         [[ "$out" =~ $connect_data_name ]] ||
23595                 {
23596                         echo "$out"
23597                         error "missing connect data $connect_data_name"
23598                 }
23599 }
23600 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23601
23602 cleanup_247() {
23603         local submount=$1
23604
23605         trap 0
23606         umount_client $submount
23607         rmdir $submount
23608 }
23609
23610 test_247a() {
23611         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23612                 grep -q subtree ||
23613                 skip_env "Fileset feature is not supported"
23614
23615         local submount=${MOUNT}_$tdir
23616
23617         mkdir $MOUNT/$tdir
23618         mkdir -p $submount || error "mkdir $submount failed"
23619         FILESET="$FILESET/$tdir" mount_client $submount ||
23620                 error "mount $submount failed"
23621         trap "cleanup_247 $submount" EXIT
23622         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23623         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23624                 error "read $MOUNT/$tdir/$tfile failed"
23625         cleanup_247 $submount
23626 }
23627 run_test 247a "mount subdir as fileset"
23628
23629 test_247b() {
23630         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23631                 skip_env "Fileset feature is not supported"
23632
23633         local submount=${MOUNT}_$tdir
23634
23635         rm -rf $MOUNT/$tdir
23636         mkdir -p $submount || error "mkdir $submount failed"
23637         SKIP_FILESET=1
23638         FILESET="$FILESET/$tdir" mount_client $submount &&
23639                 error "mount $submount should fail"
23640         rmdir $submount
23641 }
23642 run_test 247b "mount subdir that dose not exist"
23643
23644 test_247c() {
23645         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23646                 skip_env "Fileset feature is not supported"
23647
23648         local submount=${MOUNT}_$tdir
23649
23650         mkdir -p $MOUNT/$tdir/dir1
23651         mkdir -p $submount || error "mkdir $submount failed"
23652         trap "cleanup_247 $submount" EXIT
23653         FILESET="$FILESET/$tdir" mount_client $submount ||
23654                 error "mount $submount failed"
23655         local fid=$($LFS path2fid $MOUNT/)
23656         $LFS fid2path $submount $fid && error "fid2path should fail"
23657         cleanup_247 $submount
23658 }
23659 run_test 247c "running fid2path outside subdirectory root"
23660
23661 test_247d() {
23662         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23663                 skip "Fileset feature is not supported"
23664
23665         local submount=${MOUNT}_$tdir
23666
23667         mkdir -p $MOUNT/$tdir/dir1
23668         mkdir -p $submount || error "mkdir $submount failed"
23669         FILESET="$FILESET/$tdir" mount_client $submount ||
23670                 error "mount $submount failed"
23671         trap "cleanup_247 $submount" EXIT
23672
23673         local td=$submount/dir1
23674         local fid=$($LFS path2fid $td)
23675         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23676
23677         # check that we get the same pathname back
23678         local rootpath
23679         local found
23680         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23681                 echo "$rootpath $fid"
23682                 found=$($LFS fid2path $rootpath "$fid")
23683                 [ -n "$found" ] || error "fid2path should succeed"
23684                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23685         done
23686         # check wrong root path format
23687         rootpath=$submount"_wrong"
23688         found=$($LFS fid2path $rootpath "$fid")
23689         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23690
23691         cleanup_247 $submount
23692 }
23693 run_test 247d "running fid2path inside subdirectory root"
23694
23695 # LU-8037
23696 test_247e() {
23697         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23698                 grep -q subtree ||
23699                 skip "Fileset feature is not supported"
23700
23701         local submount=${MOUNT}_$tdir
23702
23703         mkdir $MOUNT/$tdir
23704         mkdir -p $submount || error "mkdir $submount failed"
23705         FILESET="$FILESET/.." mount_client $submount &&
23706                 error "mount $submount should fail"
23707         rmdir $submount
23708 }
23709 run_test 247e "mount .. as fileset"
23710
23711 test_247f() {
23712         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23713         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23714                 skip "Need at least version 2.14.50.162"
23715         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23716                 skip "Fileset feature is not supported"
23717
23718         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23719         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23720                 error "mkdir remote failed"
23721         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23722                 error "mkdir remote/subdir failed"
23723         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23724                 error "mkdir striped failed"
23725         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23726
23727         local submount=${MOUNT}_$tdir
23728
23729         mkdir -p $submount || error "mkdir $submount failed"
23730         stack_trap "rmdir $submount"
23731
23732         local dir
23733         local fileset=$FILESET
23734         local mdts=$(comma_list $(mdts_nodes))
23735
23736         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23737         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23738                 $tdir/striped/subdir $tdir/striped/.; do
23739                 FILESET="$fileset/$dir" mount_client $submount ||
23740                         error "mount $dir failed"
23741                 umount_client $submount
23742         done
23743 }
23744 run_test 247f "mount striped or remote directory as fileset"
23745
23746 test_subdir_mount_lock()
23747 {
23748         local testdir=$1
23749         local submount=${MOUNT}_$(basename $testdir)
23750
23751         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23752
23753         mkdir -p $submount || error "mkdir $submount failed"
23754         stack_trap "rmdir $submount"
23755
23756         FILESET="$fileset/$testdir" mount_client $submount ||
23757                 error "mount $FILESET failed"
23758         stack_trap "umount $submount"
23759
23760         local mdts=$(comma_list $(mdts_nodes))
23761
23762         local nrpcs
23763
23764         stat $submount > /dev/null || error "stat $submount failed"
23765         cancel_lru_locks $MDC
23766         stat $submount > /dev/null || error "stat $submount failed"
23767         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23768         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23769         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23770         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23771                 awk '/getattr/ {sum += $2} END {print sum}')
23772
23773         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23774 }
23775
23776 test_247g() {
23777         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23778
23779         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23780                 error "mkdir $tdir failed"
23781         test_subdir_mount_lock $tdir
23782 }
23783 run_test 247g "striped directory submount revalidate ROOT from cache"
23784
23785 test_247h() {
23786         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23787         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23788                 skip "Need MDS version at least 2.15.51"
23789
23790         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23791         test_subdir_mount_lock $tdir
23792         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23793         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23794                 error "mkdir $tdir.1 failed"
23795         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23796 }
23797 run_test 247h "remote directory submount revalidate ROOT from cache"
23798
23799 test_248a() {
23800         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23801         [ -z "$fast_read_sav" ] && skip "no fast read support"
23802
23803         # create a large file for fast read verification
23804         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23805
23806         # make sure the file is created correctly
23807         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23808                 { rm -f $DIR/$tfile; skip "file creation error"; }
23809
23810         echo "Test 1: verify that fast read is 4 times faster on cache read"
23811
23812         # small read with fast read enabled
23813         $LCTL set_param -n llite.*.fast_read=1
23814         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23815                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23816                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23817         # small read with fast read disabled
23818         $LCTL set_param -n llite.*.fast_read=0
23819         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23820                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23821                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23822
23823         # verify that fast read is 4 times faster for cache read
23824         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23825                 error_not_in_vm "fast read was not 4 times faster: " \
23826                            "$t_fast vs $t_slow"
23827
23828         echo "Test 2: verify the performance between big and small read"
23829         $LCTL set_param -n llite.*.fast_read=1
23830
23831         # 1k non-cache read
23832         cancel_lru_locks osc
23833         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23834                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23835                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23836
23837         # 1M non-cache read
23838         cancel_lru_locks osc
23839         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23840                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23841                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23842
23843         # verify that big IO is not 4 times faster than small IO
23844         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23845                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23846
23847         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23848         rm -f $DIR/$tfile
23849 }
23850 run_test 248a "fast read verification"
23851
23852 test_248b() {
23853         # Default short_io_bytes=16384, try both smaller and larger sizes.
23854         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23855         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23856         echo "bs=53248 count=113 normal buffered write"
23857         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23858                 error "dd of initial data file failed"
23859         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23860
23861         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23862         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23863                 error "dd with sync normal writes failed"
23864         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23865
23866         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23867         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23868                 error "dd with sync small writes failed"
23869         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23870
23871         cancel_lru_locks osc
23872
23873         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23874         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23875         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23876         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23877                 iflag=direct || error "dd with O_DIRECT small read failed"
23878         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23879         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23880                 error "compare $TMP/$tfile.1 failed"
23881
23882         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23883         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23884
23885         # just to see what the maximum tunable value is, and test parsing
23886         echo "test invalid parameter 2MB"
23887         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23888                 error "too-large short_io_bytes allowed"
23889         echo "test maximum parameter 512KB"
23890         # if we can set a larger short_io_bytes, run test regardless of version
23891         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23892                 # older clients may not allow setting it this large, that's OK
23893                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23894                         skip "Need at least client version 2.13.50"
23895                 error "medium short_io_bytes failed"
23896         fi
23897         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23898         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23899
23900         echo "test large parameter 64KB"
23901         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23902         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23903
23904         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23905         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23906                 error "dd with sync large writes failed"
23907         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23908
23909         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23910         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23911         num=$((113 * 4096 / PAGE_SIZE))
23912         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23913         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23914                 error "dd with O_DIRECT large writes failed"
23915         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23916                 error "compare $DIR/$tfile.3 failed"
23917
23918         cancel_lru_locks osc
23919
23920         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23921         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23922                 error "dd with O_DIRECT large read failed"
23923         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23924                 error "compare $TMP/$tfile.2 failed"
23925
23926         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23927         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23928                 error "dd with O_DIRECT large read failed"
23929         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23930                 error "compare $TMP/$tfile.3 failed"
23931 }
23932 run_test 248b "test short_io read and write for both small and large sizes"
23933
23934 test_248c() {
23935         $LCTL set_param llite.*.read_ahead_stats=c
23936         # This test compares whole file readahead to non-whole file readahead
23937         # The performance should be consistently slightly faster for whole file,
23938         # and the bug caused whole file readahead to be 80-100x slower, but to
23939         # account for possible test system lag, we require whole file to be
23940         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23941         # test
23942         local time1
23943         local time2
23944         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23945         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23946         counter=0
23947
23948         while [ $counter -lt 3 ]; do
23949                 # Increment the counter
23950                 ((counter++))
23951
23952                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23953                 rm -f $DIR/$tfile
23954                 touch $DIR/$tfile || error "(0) failed to create file"
23955                 # 64 MiB
23956                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23957                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23958                 echo "whole file readahead of 64 MiB took $time1 seconds"
23959                 $LCTL get_param llite.*.read_ahead_stats
23960
23961                 $LCTL set_param llite.*.read_ahead_stats=c
23962                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23963                 rm -f $DIR/$tfile
23964                 touch $DIR/$tfile || error "(2) failed to create file"
23965                 # 64 MiB
23966                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23967                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23968                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23969                 $LCTL get_param llite.*.read_ahead_stats
23970
23971                 # Check if time1 is not more than 1.5 times2
23972                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23973
23974                 if [[ $timecheck -eq 1 ]]; then
23975                         echo "Test passed on attempt $counter"
23976                         # Exit the loop
23977                         counter=4
23978                 else
23979                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23980                 fi
23981         done
23982         if [ $counter -eq 3 ]; then
23983                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
23984         fi
23985
23986 }
23987 run_test 248c "verify whole file read behavior"
23988
23989 test_249() { # LU-7890
23990         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23991                 skip "Need at least version 2.8.54"
23992
23993         rm -f $DIR/$tfile
23994         $LFS setstripe -c 1 $DIR/$tfile
23995         # Offset 2T == 4k * 512M
23996         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23997                 error "dd to 2T offset failed"
23998 }
23999 run_test 249 "Write above 2T file size"
24000
24001 test_250() {
24002         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
24003          && skip "no 16TB file size limit on ZFS"
24004
24005         $LFS setstripe -c 1 $DIR/$tfile
24006         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
24007         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
24008         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
24009         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
24010                 conv=notrunc,fsync && error "append succeeded"
24011         return 0
24012 }
24013 run_test 250 "Write above 16T limit"
24014
24015 test_251a() {
24016         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
24017
24018         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
24019         #Skip once - writing the first stripe will succeed
24020         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24021         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
24022                 error "short write happened"
24023
24024         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24025         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
24026                 error "short read happened"
24027
24028         rm -f $DIR/$tfile
24029 }
24030 run_test 251a "Handling short read and write correctly"
24031
24032 test_251b() {
24033         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24034                 error "write $tfile failed"
24035
24036         sleep 2 && echo 12345 >> $DIR/$tfile &
24037
24038         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24039         $LCTL set_param fail_loc=0x1431 fail_val=5
24040         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24041         # 5 seconds, read 10 bytes, the short read should
24042         # report:
24043         #                start ->+ read_len -> offset_after_read read_count
24044         #     short read: 4096 ->+ 10 -> 4096 0
24045         # not:
24046         #     short read: 4096 ->+ 10 -> 4102 0
24047         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24048                         awk '/short read/ { print $7 }')
24049         (( off == 4096 )) ||
24050                 error "short read should set offset at 4096, not $off"
24051 }
24052 run_test 251b "short read restore offset correctly"
24053
24054 test_252() {
24055         remote_mds_nodsh && skip "remote MDS with nodsh"
24056         remote_ost_nodsh && skip "remote OST with nodsh"
24057         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24058                 skip_env "ldiskfs only test"
24059         fi
24060
24061         local tgt
24062         local dev
24063         local out
24064         local uuid
24065         local num
24066         local gen
24067
24068         # check lr_reader on OST0000
24069         tgt=ost1
24070         dev=$(facet_device $tgt)
24071         out=$(do_facet $tgt $LR_READER $dev)
24072         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24073         echo "$out"
24074         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24075         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24076                 error "Invalid uuid returned by $LR_READER on target $tgt"
24077         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24078
24079         # check lr_reader -c on MDT0000
24080         tgt=mds1
24081         dev=$(facet_device $tgt)
24082         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24083                 skip "$LR_READER does not support additional options"
24084         fi
24085         out=$(do_facet $tgt $LR_READER -c $dev)
24086         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24087         echo "$out"
24088         num=$(echo "$out" | grep -c "mdtlov")
24089         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24090                 error "Invalid number of mdtlov clients returned by $LR_READER"
24091         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24092
24093         # check lr_reader -cr on MDT0000
24094         out=$(do_facet $tgt $LR_READER -cr $dev)
24095         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24096         echo "$out"
24097         echo "$out" | grep -q "^reply_data:$" ||
24098                 error "$LR_READER should have returned 'reply_data' section"
24099         num=$(echo "$out" | grep -c "client_generation")
24100         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24101 }
24102 run_test 252 "check lr_reader tool"
24103
24104 test_253() {
24105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24106         remote_mds_nodsh && skip "remote MDS with nodsh"
24107         remote_mgs_nodsh && skip "remote MGS with nodsh"
24108         check_set_fallocate_or_skip
24109
24110         local ostidx=0
24111         local rc=0
24112         local ost_name=$(ostname_from_index $ostidx)
24113
24114         # on the mdt's osc
24115         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24116         do_facet $SINGLEMDS $LCTL get_param -n \
24117                 osp.$mdtosc_proc1.reserved_mb_high ||
24118                 skip  "remote MDS does not support reserved_mb_high"
24119
24120         rm -rf $DIR/$tdir
24121         wait_mds_ost_sync
24122         wait_delete_completed
24123         mkdir $DIR/$tdir
24124         stack_trap "rm -rf $DIR/$tdir"
24125
24126         pool_add $TESTNAME || error "Pool creation failed"
24127         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24128
24129         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24130                 error "Setstripe failed"
24131
24132         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24133
24134         local wms=$(ost_watermarks_get $ostidx)
24135
24136         ost_watermarks_set $ostidx 60 50
24137         stack_trap "ost_watermarks_set $ostidx $wms"
24138
24139         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24140         local size=$((free_kb * 1024))
24141
24142         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24143                 error "fallocate failed"
24144         sleep_maxage
24145
24146         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24147                         osp.$mdtosc_proc1.prealloc_status)
24148         echo "prealloc_status $oa_status"
24149
24150         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24151                 error "File creation should fail"
24152
24153         #object allocation was stopped, but we still able to append files
24154         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24155                 oflag=append || error "Append failed"
24156
24157         rm -f $DIR/$tdir/$tfile.0
24158         rm -f $DIR/$tdir/fill_ost$ostidx
24159
24160         wait_delete_completed
24161         sleep_maxage
24162
24163         for i in $(seq 10 12); do
24164                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24165                         2>/dev/null || error "File creation failed after rm"
24166         done
24167
24168         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24169                         osp.$mdtosc_proc1.prealloc_status)
24170         echo "prealloc_status $oa_status"
24171
24172         if (( oa_status != 0 )); then
24173                 error "Object allocation still disable after rm"
24174         fi
24175 }
24176 run_test 253 "Check object allocation limit"
24177
24178 test_254() {
24179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24180         remote_mds_nodsh && skip "remote MDS with nodsh"
24181
24182         local mdt=$(facet_svc $SINGLEMDS)
24183
24184         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24185                 skip "MDS does not support changelog_size"
24186
24187         local cl_user
24188
24189         changelog_register || error "changelog_register failed"
24190
24191         changelog_clear 0 || error "changelog_clear failed"
24192
24193         local size1=$(do_facet $SINGLEMDS \
24194                       $LCTL get_param -n mdd.$mdt.changelog_size)
24195         echo "Changelog size $size1"
24196
24197         rm -rf $DIR/$tdir
24198         $LFS mkdir -i 0 $DIR/$tdir
24199         # change something
24200         mkdir -p $DIR/$tdir/pics/2008/zachy
24201         touch $DIR/$tdir/pics/2008/zachy/timestamp
24202         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24203         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24204         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24205         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24206         rm $DIR/$tdir/pics/desktop.jpg
24207
24208         local size2=$(do_facet $SINGLEMDS \
24209                       $LCTL get_param -n mdd.$mdt.changelog_size)
24210         echo "Changelog size after work $size2"
24211
24212         (( $size2 > $size1 )) ||
24213                 error "new Changelog size=$size2 less than old size=$size1"
24214 }
24215 run_test 254 "Check changelog size"
24216
24217 ladvise_no_type()
24218 {
24219         local type=$1
24220         local file=$2
24221
24222         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24223                 awk -F: '{print $2}' | grep $type > /dev/null
24224         if [ $? -ne 0 ]; then
24225                 return 0
24226         fi
24227         return 1
24228 }
24229
24230 ladvise_no_ioctl()
24231 {
24232         local file=$1
24233
24234         lfs ladvise -a willread $file > /dev/null 2>&1
24235         if [ $? -eq 0 ]; then
24236                 return 1
24237         fi
24238
24239         lfs ladvise -a willread $file 2>&1 |
24240                 grep "Inappropriate ioctl for device" > /dev/null
24241         if [ $? -eq 0 ]; then
24242                 return 0
24243         fi
24244         return 1
24245 }
24246
24247 percent() {
24248         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24249 }
24250
24251 # run a random read IO workload
24252 # usage: random_read_iops <filename> <filesize> <iosize>
24253 random_read_iops() {
24254         local file=$1
24255         local fsize=$2
24256         local iosize=${3:-4096}
24257
24258         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24259                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24260 }
24261
24262 drop_file_oss_cache() {
24263         local file="$1"
24264         local nodes="$2"
24265
24266         $LFS ladvise -a dontneed $file 2>/dev/null ||
24267                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24268 }
24269
24270 ladvise_willread_performance()
24271 {
24272         local repeat=10
24273         local average_origin=0
24274         local average_cache=0
24275         local average_ladvise=0
24276
24277         for ((i = 1; i <= $repeat; i++)); do
24278                 echo "Iter $i/$repeat: reading without willread hint"
24279                 cancel_lru_locks osc
24280                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24281                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24282                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24283                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24284
24285                 cancel_lru_locks osc
24286                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24287                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24288                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24289
24290                 cancel_lru_locks osc
24291                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24292                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24293                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24294                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24295                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24296         done
24297         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24298         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24299         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24300
24301         speedup_cache=$(percent $average_cache $average_origin)
24302         speedup_ladvise=$(percent $average_ladvise $average_origin)
24303
24304         echo "Average uncached read: $average_origin"
24305         echo "Average speedup with OSS cached read:" \
24306                 "$average_cache = +$speedup_cache%"
24307         echo "Average speedup with ladvise willread:" \
24308                 "$average_ladvise = +$speedup_ladvise%"
24309
24310         local lowest_speedup=20
24311         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24312                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24313                      "got $speedup_cache%. Skipping ladvise willread check."
24314                 return 0
24315         fi
24316
24317         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24318         # it is still good to run until then to exercise 'ladvise willread'
24319         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24320                 [ "$ost1_FSTYPE" = "zfs" ] &&
24321                 echo "osd-zfs does not support dontneed or drop_caches" &&
24322                 return 0
24323
24324         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24325         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24326                 error_not_in_vm "Speedup with willread is less than " \
24327                         "$lowest_speedup%, got $speedup_ladvise%"
24328 }
24329
24330 test_255a() {
24331         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24332                 skip "lustre < 2.8.54 does not support ladvise "
24333         remote_ost_nodsh && skip "remote OST with nodsh"
24334
24335         stack_trap "rm -f $DIR/$tfile"
24336         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24337
24338         ladvise_no_type willread $DIR/$tfile &&
24339                 skip "willread ladvise is not supported"
24340
24341         ladvise_no_ioctl $DIR/$tfile &&
24342                 skip "ladvise ioctl is not supported"
24343
24344         local size_mb=100
24345         local size=$((size_mb * 1048576))
24346         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24347                 error "dd to $DIR/$tfile failed"
24348
24349         lfs ladvise -a willread $DIR/$tfile ||
24350                 error "Ladvise failed with no range argument"
24351
24352         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24353                 error "Ladvise failed with no -l or -e argument"
24354
24355         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24356                 error "Ladvise failed with only -e argument"
24357
24358         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24359                 error "Ladvise failed with only -l argument"
24360
24361         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24362                 error "End offset should not be smaller than start offset"
24363
24364         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24365                 error "End offset should not be equal to start offset"
24366
24367         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24368                 error "Ladvise failed with overflowing -s argument"
24369
24370         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24371                 error "Ladvise failed with overflowing -e argument"
24372
24373         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24374                 error "Ladvise failed with overflowing -l argument"
24375
24376         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24377                 error "Ladvise succeeded with conflicting -l and -e arguments"
24378
24379         echo "Synchronous ladvise should wait"
24380         local delay=8
24381 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24382         do_nodes $(comma_list $(osts_nodes)) \
24383                 $LCTL set_param fail_val=$delay fail_loc=0x237
24384         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24385                 $LCTL set_param fail_loc=0"
24386
24387         local start_ts=$SECONDS
24388         lfs ladvise -a willread $DIR/$tfile ||
24389                 error "Ladvise failed with no range argument"
24390         local end_ts=$SECONDS
24391         local inteval_ts=$((end_ts - start_ts))
24392
24393         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24394                 error "Synchronous advice didn't wait reply"
24395         fi
24396
24397         echo "Asynchronous ladvise shouldn't wait"
24398         local start_ts=$SECONDS
24399         lfs ladvise -a willread -b $DIR/$tfile ||
24400                 error "Ladvise failed with no range argument"
24401         local end_ts=$SECONDS
24402         local inteval_ts=$((end_ts - start_ts))
24403
24404         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24405                 error "Asynchronous advice blocked"
24406         fi
24407
24408         ladvise_willread_performance
24409 }
24410 run_test 255a "check 'lfs ladvise -a willread'"
24411
24412 facet_meminfo() {
24413         local facet=$1
24414         local info=$2
24415
24416         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24417 }
24418
24419 test_255b() {
24420         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24421                 skip "lustre < 2.8.54 does not support ladvise "
24422         remote_ost_nodsh && skip "remote OST with nodsh"
24423
24424         stack_trap "rm -f $DIR/$tfile"
24425         lfs setstripe -c 1 -i 0 $DIR/$tfile
24426
24427         ladvise_no_type dontneed $DIR/$tfile &&
24428                 skip "dontneed ladvise is not supported"
24429
24430         ladvise_no_ioctl $DIR/$tfile &&
24431                 skip "ladvise ioctl is not supported"
24432
24433         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24434                 [ "$ost1_FSTYPE" = "zfs" ] &&
24435                 skip "zfs-osd does not support 'ladvise dontneed'"
24436
24437         local size_mb=100
24438         local size=$((size_mb * 1048576))
24439         # In order to prevent disturbance of other processes, only check 3/4
24440         # of the memory usage
24441         local kibibytes=$((size_mb * 1024 * 3 / 4))
24442
24443         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24444                 error "dd to $DIR/$tfile failed"
24445
24446         #force write to complete before dropping OST cache & checking memory
24447         sync
24448
24449         local total=$(facet_meminfo ost1 MemTotal)
24450         echo "Total memory: $total KiB"
24451
24452         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24453         local before_read=$(facet_meminfo ost1 Cached)
24454         echo "Cache used before read: $before_read KiB"
24455
24456         lfs ladvise -a willread $DIR/$tfile ||
24457                 error "Ladvise willread failed"
24458         local after_read=$(facet_meminfo ost1 Cached)
24459         echo "Cache used after read: $after_read KiB"
24460
24461         lfs ladvise -a dontneed $DIR/$tfile ||
24462                 error "Ladvise dontneed again failed"
24463         local no_read=$(facet_meminfo ost1 Cached)
24464         echo "Cache used after dontneed ladvise: $no_read KiB"
24465
24466         if [ $total -lt $((before_read + kibibytes)) ]; then
24467                 echo "Memory is too small, abort checking"
24468                 return 0
24469         fi
24470
24471         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24472                 error "Ladvise willread should use more memory" \
24473                         "than $kibibytes KiB"
24474         fi
24475
24476         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24477                 error "Ladvise dontneed should release more memory" \
24478                         "than $kibibytes KiB"
24479         fi
24480 }
24481 run_test 255b "check 'lfs ladvise -a dontneed'"
24482
24483 test_255c() {
24484         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24485                 skip "lustre < 2.10.50 does not support lockahead"
24486
24487         local ost1_imp=$(get_osc_import_name client ost1)
24488         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24489                          cut -d'.' -f2)
24490         local count
24491         local new_count
24492         local difference
24493         local i
24494         local rc
24495
24496         test_mkdir -p $DIR/$tdir
24497         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24498
24499         #test 10 returns only success/failure
24500         i=10
24501         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24502         rc=$?
24503         if [ $rc -eq 255 ]; then
24504                 error "Ladvise test${i} failed, ${rc}"
24505         fi
24506
24507         #test 11 counts lock enqueue requests, all others count new locks
24508         i=11
24509         count=$(do_facet ost1 \
24510                 $LCTL get_param -n ost.OSS.ost.stats)
24511         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24512
24513         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24514         rc=$?
24515         if [ $rc -eq 255 ]; then
24516                 error "Ladvise test${i} failed, ${rc}"
24517         fi
24518
24519         new_count=$(do_facet ost1 \
24520                 $LCTL get_param -n ost.OSS.ost.stats)
24521         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24522                    awk '{ print $2 }')
24523
24524         difference="$((new_count - count))"
24525         if [ $difference -ne $rc ]; then
24526                 error "Ladvise test${i}, bad enqueue count, returned " \
24527                       "${rc}, actual ${difference}"
24528         fi
24529
24530         for i in $(seq 12 21); do
24531                 # If we do not do this, we run the risk of having too many
24532                 # locks and starting lock cancellation while we are checking
24533                 # lock counts.
24534                 cancel_lru_locks osc
24535
24536                 count=$($LCTL get_param -n \
24537                        ldlm.namespaces.$imp_name.lock_unused_count)
24538
24539                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24540                 rc=$?
24541                 if [ $rc -eq 255 ]; then
24542                         error "Ladvise test ${i} failed, ${rc}"
24543                 fi
24544
24545                 new_count=$($LCTL get_param -n \
24546                        ldlm.namespaces.$imp_name.lock_unused_count)
24547                 difference="$((new_count - count))"
24548
24549                 # Test 15 output is divided by 100 to map down to valid return
24550                 if [ $i -eq 15 ]; then
24551                         rc="$((rc * 100))"
24552                 fi
24553
24554                 if [ $difference -ne $rc ]; then
24555                         error "Ladvise test ${i}, bad lock count, returned " \
24556                               "${rc}, actual ${difference}"
24557                 fi
24558         done
24559
24560         #test 22 returns only success/failure
24561         i=22
24562         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24563         rc=$?
24564         if [ $rc -eq 255 ]; then
24565                 error "Ladvise test${i} failed, ${rc}"
24566         fi
24567 }
24568 run_test 255c "suite of ladvise lockahead tests"
24569
24570 test_256() {
24571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24572         remote_mds_nodsh && skip "remote MDS with nodsh"
24573         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24574         changelog_users $SINGLEMDS | grep "^cl" &&
24575                 skip "active changelog user"
24576
24577         local cl_user
24578         local cat_sl
24579         local mdt_dev
24580
24581         mdt_dev=$(facet_device $SINGLEMDS)
24582         echo $mdt_dev
24583
24584         changelog_register || error "changelog_register failed"
24585
24586         rm -rf $DIR/$tdir
24587         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24588
24589         changelog_clear 0 || error "changelog_clear failed"
24590
24591         # change something
24592         touch $DIR/$tdir/{1..10}
24593
24594         # stop the MDT
24595         stop $SINGLEMDS || error "Fail to stop MDT"
24596
24597         # remount the MDT
24598         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24599                 error "Fail to start MDT"
24600
24601         #after mount new plainllog is used
24602         touch $DIR/$tdir/{11..19}
24603         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24604         stack_trap "rm -f $tmpfile"
24605         cat_sl=$(do_facet $SINGLEMDS "sync; \
24606                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24607                  llog_reader $tmpfile | grep -c type=1064553b")
24608         do_facet $SINGLEMDS llog_reader $tmpfile
24609
24610         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24611
24612         changelog_clear 0 || error "changelog_clear failed"
24613
24614         cat_sl=$(do_facet $SINGLEMDS "sync; \
24615                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24616                  llog_reader $tmpfile | grep -c type=1064553b")
24617
24618         if (( cat_sl == 2 )); then
24619                 error "Empty plain llog was not deleted from changelog catalog"
24620         elif (( cat_sl != 1 )); then
24621                 error "Active plain llog shouldn't be deleted from catalog"
24622         fi
24623 }
24624 run_test 256 "Check llog delete for empty and not full state"
24625
24626 test_257() {
24627         remote_mds_nodsh && skip "remote MDS with nodsh"
24628         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24629                 skip "Need MDS version at least 2.8.55"
24630
24631         test_mkdir $DIR/$tdir
24632
24633         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24634                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24635         stat $DIR/$tdir
24636
24637 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24638         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24639         local facet=mds$((mdtidx + 1))
24640         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24641         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24642
24643         stop $facet || error "stop MDS failed"
24644         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24645                 error "start MDS fail"
24646         wait_recovery_complete $facet
24647 }
24648 run_test 257 "xattr locks are not lost"
24649
24650 # Verify we take the i_mutex when security requires it
24651 test_258a() {
24652 #define OBD_FAIL_IMUTEX_SEC 0x141c
24653         $LCTL set_param fail_loc=0x141c
24654         touch $DIR/$tfile
24655         chmod u+s $DIR/$tfile
24656         chmod a+rwx $DIR/$tfile
24657         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24658         RC=$?
24659         if [ $RC -ne 0 ]; then
24660                 error "error, failed to take i_mutex, rc=$?"
24661         fi
24662         rm -f $DIR/$tfile
24663 }
24664 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24665
24666 # Verify we do NOT take the i_mutex in the normal case
24667 test_258b() {
24668 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24669         $LCTL set_param fail_loc=0x141d
24670         touch $DIR/$tfile
24671         chmod a+rwx $DIR
24672         chmod a+rw $DIR/$tfile
24673         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24674         RC=$?
24675         if [ $RC -ne 0 ]; then
24676                 error "error, took i_mutex unnecessarily, rc=$?"
24677         fi
24678         rm -f $DIR/$tfile
24679
24680 }
24681 run_test 258b "verify i_mutex security behavior"
24682
24683 test_259() {
24684         local file=$DIR/$tfile
24685         local before
24686         local after
24687
24688         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24689
24690         stack_trap "rm -f $file" EXIT
24691
24692         wait_delete_completed
24693         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24694         echo "before: $before"
24695
24696         $LFS setstripe -i 0 -c 1 $file
24697         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24698         sync_all_data
24699         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24700         echo "after write: $after"
24701
24702 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24703         do_facet ost1 $LCTL set_param fail_loc=0x2301
24704         $TRUNCATE $file 0
24705         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24706         echo "after truncate: $after"
24707
24708         stop ost1
24709         do_facet ost1 $LCTL set_param fail_loc=0
24710         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24711         sleep 2
24712         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24713         echo "after restart: $after"
24714         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24715                 error "missing truncate?"
24716
24717         return 0
24718 }
24719 run_test 259 "crash at delayed truncate"
24720
24721 test_260() {
24722 #define OBD_FAIL_MDC_CLOSE               0x806
24723         $LCTL set_param fail_loc=0x80000806
24724         touch $DIR/$tfile
24725
24726 }
24727 run_test 260 "Check mdc_close fail"
24728
24729 ### Data-on-MDT sanity tests ###
24730 test_270a() {
24731         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24732                 skip "Need MDS version at least 2.10.55 for DoM"
24733
24734         # create DoM file
24735         local dom=$DIR/$tdir/dom_file
24736         local tmp=$DIR/$tdir/tmp_file
24737
24738         mkdir_on_mdt0 $DIR/$tdir
24739
24740         # basic checks for DoM component creation
24741         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24742                 error "Can set MDT layout to non-first entry"
24743
24744         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24745                 error "Can define multiple entries as MDT layout"
24746
24747         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24748
24749         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24750         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24751         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24752
24753         local mdtidx=$($LFS getstripe -m $dom)
24754         local mdtname=MDT$(printf %04x $mdtidx)
24755         local facet=mds$((mdtidx + 1))
24756         local space_check=1
24757
24758         # Skip free space checks with ZFS
24759         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24760
24761         # write
24762         sync
24763         local size_tmp=$((65536 * 3))
24764         local mdtfree1=$(do_facet $facet \
24765                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24766
24767         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24768         # check also direct IO along write
24769         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24770         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24771         sync
24772         cmp $tmp $dom || error "file data is different"
24773         [ $(stat -c%s $dom) == $size_tmp ] ||
24774                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24775         if [ $space_check == 1 ]; then
24776                 local mdtfree2=$(do_facet $facet \
24777                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24778
24779                 # increase in usage from by $size_tmp
24780                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24781                         error "MDT free space wrong after write: " \
24782                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24783         fi
24784
24785         # truncate
24786         local size_dom=10000
24787
24788         $TRUNCATE $dom $size_dom
24789         [ $(stat -c%s $dom) == $size_dom ] ||
24790                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24791         if [ $space_check == 1 ]; then
24792                 mdtfree1=$(do_facet $facet \
24793                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24794                 # decrease in usage from $size_tmp to new $size_dom
24795                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24796                   $(((size_tmp - size_dom) / 1024)) ] ||
24797                         error "MDT free space is wrong after truncate: " \
24798                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24799         fi
24800
24801         # append
24802         cat $tmp >> $dom
24803         sync
24804         size_dom=$((size_dom + size_tmp))
24805         [ $(stat -c%s $dom) == $size_dom ] ||
24806                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24807         if [ $space_check == 1 ]; then
24808                 mdtfree2=$(do_facet $facet \
24809                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24810                 # increase in usage by $size_tmp from previous
24811                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24812                         error "MDT free space is wrong after append: " \
24813                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24814         fi
24815
24816         # delete
24817         rm $dom
24818         if [ $space_check == 1 ]; then
24819                 mdtfree1=$(do_facet $facet \
24820                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24821                 # decrease in usage by $size_dom from previous
24822                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24823                         error "MDT free space is wrong after removal: " \
24824                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24825         fi
24826
24827         # combined striping
24828         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24829                 error "Can't create DoM + OST striping"
24830
24831         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24832         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24833         # check also direct IO along write
24834         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24835         sync
24836         cmp $tmp $dom || error "file data is different"
24837         [ $(stat -c%s $dom) == $size_tmp ] ||
24838                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24839         rm $dom $tmp
24840
24841         return 0
24842 }
24843 run_test 270a "DoM: basic functionality tests"
24844
24845 test_270b() {
24846         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24847                 skip "Need MDS version at least 2.10.55"
24848
24849         local dom=$DIR/$tdir/dom_file
24850         local max_size=1048576
24851
24852         mkdir -p $DIR/$tdir
24853         $LFS setstripe -E $max_size -L mdt $dom
24854
24855         # truncate over the limit
24856         $TRUNCATE $dom $(($max_size + 1)) &&
24857                 error "successful truncate over the maximum size"
24858         # write over the limit
24859         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24860                 error "successful write over the maximum size"
24861         # append over the limit
24862         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24863         echo "12345" >> $dom && error "successful append over the maximum size"
24864         rm $dom
24865
24866         return 0
24867 }
24868 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24869
24870 test_270c() {
24871         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24872                 skip "Need MDS version at least 2.10.55"
24873
24874         mkdir -p $DIR/$tdir
24875         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24876
24877         # check files inherit DoM EA
24878         touch $DIR/$tdir/first
24879         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24880                 error "bad pattern"
24881         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24882                 error "bad stripe count"
24883         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24884                 error "bad stripe size"
24885
24886         # check directory inherits DoM EA and uses it as default
24887         mkdir $DIR/$tdir/subdir
24888         touch $DIR/$tdir/subdir/second
24889         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24890                 error "bad pattern in sub-directory"
24891         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24892                 error "bad stripe count in sub-directory"
24893         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24894                 error "bad stripe size in sub-directory"
24895         return 0
24896 }
24897 run_test 270c "DoM: DoM EA inheritance tests"
24898
24899 test_270d() {
24900         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24901                 skip "Need MDS version at least 2.10.55"
24902
24903         mkdir -p $DIR/$tdir
24904         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24905
24906         # inherit default DoM striping
24907         mkdir $DIR/$tdir/subdir
24908         touch $DIR/$tdir/subdir/f1
24909
24910         # change default directory striping
24911         $LFS setstripe -c 1 $DIR/$tdir/subdir
24912         touch $DIR/$tdir/subdir/f2
24913         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24914                 error "wrong default striping in file 2"
24915         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24916                 error "bad pattern in file 2"
24917         return 0
24918 }
24919 run_test 270d "DoM: change striping from DoM to RAID0"
24920
24921 test_270e() {
24922         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24923                 skip "Need MDS version at least 2.10.55"
24924
24925         mkdir -p $DIR/$tdir/dom
24926         mkdir -p $DIR/$tdir/norm
24927         DOMFILES=20
24928         NORMFILES=10
24929         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24930         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24931
24932         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24933         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24934
24935         # find DoM files by layout
24936         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24937         [ $NUM -eq  $DOMFILES ] ||
24938                 error "lfs find -L: found $NUM, expected $DOMFILES"
24939         echo "Test 1: lfs find 20 DOM files by layout: OK"
24940
24941         # there should be 1 dir with default DOM striping
24942         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24943         [ $NUM -eq  1 ] ||
24944                 error "lfs find -L: found $NUM, expected 1 dir"
24945         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24946
24947         # find DoM files by stripe size
24948         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24949         [ $NUM -eq  $DOMFILES ] ||
24950                 error "lfs find -S: found $NUM, expected $DOMFILES"
24951         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24952
24953         # find files by stripe offset except DoM files
24954         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24955         [ $NUM -eq  $NORMFILES ] ||
24956                 error "lfs find -i: found $NUM, expected $NORMFILES"
24957         echo "Test 5: lfs find no DOM files by stripe index: OK"
24958         return 0
24959 }
24960 run_test 270e "DoM: lfs find with DoM files test"
24961
24962 test_270f() {
24963         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24964                 skip "Need MDS version at least 2.10.55"
24965
24966         local mdtname=${FSNAME}-MDT0000-mdtlov
24967         local dom=$DIR/$tdir/dom_file
24968         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24969                                                 lod.$mdtname.dom_stripesize)
24970         local dom_limit=131072
24971
24972         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24973         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24974                                                 lod.$mdtname.dom_stripesize)
24975         [ ${dom_limit} -eq ${dom_current} ] ||
24976                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24977
24978         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24979         $LFS setstripe -d $DIR/$tdir
24980         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24981                 error "Can't set directory default striping"
24982
24983         # exceed maximum stripe size
24984         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24985                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24986         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24987                 error "Able to create DoM component size more than LOD limit"
24988
24989         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24990         dom_current=$(do_facet mds1 $LCTL get_param -n \
24991                                                 lod.$mdtname.dom_stripesize)
24992         [ 0 -eq ${dom_current} ] ||
24993                 error "Can't set zero DoM stripe limit"
24994         rm $dom
24995
24996         # attempt to create DoM file on server with disabled DoM should
24997         # remove DoM entry from layout and be succeed
24998         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24999                 error "Can't create DoM file (DoM is disabled)"
25000         [ $($LFS getstripe -L $dom) == "mdt" ] &&
25001                 error "File has DoM component while DoM is disabled"
25002         rm $dom
25003
25004         # attempt to create DoM file with only DoM stripe should return error
25005         $LFS setstripe -E $dom_limit -L mdt $dom &&
25006                 error "Able to create DoM-only file while DoM is disabled"
25007
25008         # too low values to be aligned with smallest stripe size 64K
25009         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
25010         dom_current=$(do_facet mds1 $LCTL get_param -n \
25011                                                 lod.$mdtname.dom_stripesize)
25012         [ 30000 -eq ${dom_current} ] &&
25013                 error "Can set too small DoM stripe limit"
25014
25015         # 64K is a minimal stripe size in Lustre, expect limit of that size
25016         [ 65536 -eq ${dom_current} ] ||
25017                 error "Limit is not set to 64K but ${dom_current}"
25018
25019         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
25020         dom_current=$(do_facet mds1 $LCTL get_param -n \
25021                                                 lod.$mdtname.dom_stripesize)
25022         echo $dom_current
25023         [ 2147483648 -eq ${dom_current} ] &&
25024                 error "Can set too large DoM stripe limit"
25025
25026         do_facet mds1 $LCTL set_param -n \
25027                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
25028         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25029                 error "Can't create DoM component size after limit change"
25030         do_facet mds1 $LCTL set_param -n \
25031                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
25032         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25033                 error "Can't create DoM file after limit decrease"
25034         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25035                 error "Can create big DoM component after limit decrease"
25036         touch ${dom}_def ||
25037                 error "Can't create file with old default layout"
25038
25039         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25040         return 0
25041 }
25042 run_test 270f "DoM: maximum DoM stripe size checks"
25043
25044 test_270g() {
25045         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25046                 skip "Need MDS version at least 2.13.52"
25047         local dom=$DIR/$tdir/$tfile
25048
25049         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25050         local lodname=${FSNAME}-MDT0000-mdtlov
25051
25052         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25053         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25054         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25055         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25056
25057         local dom_limit=1024
25058         local dom_threshold="50%"
25059
25060         $LFS setstripe -d $DIR/$tdir
25061         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25062                 error "Can't set directory default striping"
25063
25064         do_facet mds1 $LCTL set_param -n \
25065                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25066         # set 0 threshold and create DOM file to change tunable stripesize
25067         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25068         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25069                 error "Failed to create $dom file"
25070         # now tunable dom_cur_stripesize should reach maximum
25071         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25072                                         lod.${lodname}.dom_stripesize_cur_kb)
25073         [[ $dom_current == $dom_limit ]] ||
25074                 error "Current DOM stripesize is not maximum"
25075         rm $dom
25076
25077         # set threshold for further tests
25078         do_facet mds1 $LCTL set_param -n \
25079                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25080         echo "DOM threshold is $dom_threshold free space"
25081         local dom_def
25082         local dom_set
25083         # Spoof bfree to exceed threshold
25084         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25085         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25086         for spfree in 40 20 0 15 30 55; do
25087                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25088                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25089                         error "Failed to create $dom file"
25090                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25091                                         lod.${lodname}.dom_stripesize_cur_kb)
25092                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25093                 [[ $dom_def != $dom_current ]] ||
25094                         error "Default stripe size was not changed"
25095                 if (( spfree > 0 )) ; then
25096                         dom_set=$($LFS getstripe -S $dom)
25097                         (( dom_set == dom_def * 1024 )) ||
25098                                 error "DOM component size is still old"
25099                 else
25100                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25101                                 error "DoM component is set with no free space"
25102                 fi
25103                 rm $dom
25104                 dom_current=$dom_def
25105         done
25106 }
25107 run_test 270g "DoM: default DoM stripe size depends on free space"
25108
25109 test_270h() {
25110         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25111                 skip "Need MDS version at least 2.13.53"
25112
25113         local mdtname=${FSNAME}-MDT0000-mdtlov
25114         local dom=$DIR/$tdir/$tfile
25115         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25116
25117         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25118         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25119
25120         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25121         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25122                 error "can't create OST file"
25123         # mirrored file with DOM entry in the second mirror
25124         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25125                 error "can't create mirror with DoM component"
25126
25127         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25128
25129         # DOM component in the middle and has other enries in the same mirror,
25130         # should succeed but lost DoM component
25131         $LFS setstripe --copy=${dom}_1 $dom ||
25132                 error "Can't create file from OST|DOM mirror layout"
25133         # check new file has no DoM layout after all
25134         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25135                 error "File has DoM component while DoM is disabled"
25136 }
25137 run_test 270h "DoM: DoM stripe removal when disabled on server"
25138
25139 test_270i() {
25140         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25141                 skip "Need MDS version at least 2.14.54"
25142
25143         mkdir $DIR/$tdir
25144         # DoM with plain layout
25145         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25146                 error "default plain layout with DoM must fail"
25147         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25148                 error "setstripe plain file layout with DoM must fail"
25149         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25150                 error "default DoM layout with bad striping must fail"
25151         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25152                 error "setstripe to DoM layout with bad striping must fail"
25153         return 0
25154 }
25155 run_test 270i "DoM: setting invalid DoM striping should fail"
25156
25157 test_270j() {
25158         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25159                 skip "Need MDS version at least 2.15.55.203"
25160
25161         local dom=$DIR/$tdir/$tfile
25162         local odv
25163         local ndv
25164
25165         mkdir -p $DIR/$tdir
25166
25167         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25168
25169         odv=$($LFS data_version $dom)
25170         chmod 666 $dom
25171         mv $dom ${dom}_moved
25172         link ${dom}_moved $dom
25173         setfattr -n user.attrx -v "some_attr" $dom
25174         ndv=$($LFS data_version $dom)
25175         (( $ndv == $odv )) ||
25176                 error "data version was changed by metadata operations"
25177
25178         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25179                 error "failed to write data into $dom"
25180         cancel_lru_locks mdc
25181         ndv=$($LFS data_version $dom)
25182         (( $ndv != $odv )) ||
25183                 error "data version wasn't changed on write"
25184
25185         odv=$ndv
25186         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25187         ndv=$($LFS data_version $dom)
25188         (( $ndv != $odv )) ||
25189                 error "data version wasn't changed on truncate down"
25190
25191         odv=$ndv
25192         $TRUNCATE $dom 25000
25193         ndv=$($LFS data_version $dom)
25194         (( $ndv != $odv )) ||
25195                 error "data version wasn't changed on truncate up"
25196
25197         # check also fallocate for ldiskfs
25198         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25199                 odv=$ndv
25200                 fallocate -l 1048576 $dom
25201                 ndv=$($LFS data_version $dom)
25202                 (( $ndv != $odv )) ||
25203                         error "data version wasn't changed on fallocate"
25204
25205                 odv=$ndv
25206                 fallocate -p --offset 4096 -l 4096 $dom
25207                 ndv=$($LFS data_version $dom)
25208                 (( $ndv != $odv )) ||
25209                         error "data version wasn't changed on fallocate punch"
25210         fi
25211 }
25212 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25213
25214 test_271a() {
25215         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25216                 skip "Need MDS version at least 2.10.55"
25217
25218         local dom=$DIR/$tdir/dom
25219
25220         mkdir -p $DIR/$tdir
25221
25222         $LFS setstripe -E 1024K -L mdt $dom
25223
25224         lctl set_param -n mdc.*.stats=clear
25225         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25226         cat $dom > /dev/null
25227         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25228         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25229         ls $dom
25230         rm -f $dom
25231 }
25232 run_test 271a "DoM: data is cached for read after write"
25233
25234 test_271b() {
25235         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25236                 skip "Need MDS version at least 2.10.55"
25237
25238         local dom=$DIR/$tdir/dom
25239
25240         mkdir -p $DIR/$tdir
25241
25242         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25243
25244         lctl set_param -n mdc.*.stats=clear
25245         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25246         cancel_lru_locks mdc
25247         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25248         # second stat to check size is cached on client
25249         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25250         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25251         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25252         rm -f $dom
25253 }
25254 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25255
25256 test_271ba() {
25257         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25258                 skip "Need MDS version at least 2.10.55"
25259
25260         local dom=$DIR/$tdir/dom
25261
25262         mkdir -p $DIR/$tdir
25263
25264         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25265
25266         lctl set_param -n mdc.*.stats=clear
25267         lctl set_param -n osc.*.stats=clear
25268         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25269         cancel_lru_locks mdc
25270         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25271         # second stat to check size is cached on client
25272         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25273         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25274         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25275         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25276         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25277         rm -f $dom
25278 }
25279 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25280
25281
25282 get_mdc_stats() {
25283         local mdtidx=$1
25284         local param=$2
25285         local mdt=MDT$(printf %04x $mdtidx)
25286
25287         if [ -z $param ]; then
25288                 lctl get_param -n mdc.*$mdt*.stats
25289         else
25290                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25291         fi
25292 }
25293
25294 test_271c() {
25295         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25296                 skip "Need MDS version at least 2.10.55"
25297
25298         local dom=$DIR/$tdir/dom
25299
25300         mkdir -p $DIR/$tdir
25301
25302         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25303
25304         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25305         local facet=mds$((mdtidx + 1))
25306
25307         cancel_lru_locks mdc
25308         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25309         createmany -o $dom 1000
25310         lctl set_param -n mdc.*.stats=clear
25311         smalliomany -w $dom 1000 200
25312         get_mdc_stats $mdtidx
25313         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25314         # Each file has 1 open, 1 IO enqueues, total 2000
25315         # but now we have also +1 getxattr for security.capability, total 3000
25316         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25317         unlinkmany $dom 1000
25318
25319         cancel_lru_locks mdc
25320         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25321         createmany -o $dom 1000
25322         lctl set_param -n mdc.*.stats=clear
25323         smalliomany -w $dom 1000 200
25324         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25325         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25326         # for OPEN and IO lock.
25327         [ $((enq - enq_2)) -ge 1000 ] ||
25328                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25329         unlinkmany $dom 1000
25330         return 0
25331 }
25332 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25333
25334 cleanup_271def_tests() {
25335         trap 0
25336         rm -f $1
25337 }
25338
25339 test_271d() {
25340         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25341                 skip "Need MDS version at least 2.10.57"
25342
25343         local dom=$DIR/$tdir/dom
25344         local tmp=$TMP/$tfile
25345         trap "cleanup_271def_tests $tmp" EXIT
25346
25347         mkdir -p $DIR/$tdir
25348
25349         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25350
25351         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25352
25353         cancel_lru_locks mdc
25354         dd if=/dev/urandom of=$tmp bs=1000 count=1
25355         dd if=$tmp of=$dom bs=1000 count=1
25356         cancel_lru_locks mdc
25357
25358         cat /etc/hosts >> $tmp
25359         lctl set_param -n mdc.*.stats=clear
25360
25361         # append data to the same file it should update local page
25362         echo "Append to the same page"
25363         cat /etc/hosts >> $dom
25364         local num=$(get_mdc_stats $mdtidx ost_read)
25365         local ra=$(get_mdc_stats $mdtidx req_active)
25366         local rw=$(get_mdc_stats $mdtidx req_waittime)
25367
25368         [ -z $num ] || error "$num READ RPC occured"
25369         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25370         echo "... DONE"
25371
25372         # compare content
25373         cmp $tmp $dom || error "file miscompare"
25374
25375         cancel_lru_locks mdc
25376         lctl set_param -n mdc.*.stats=clear
25377
25378         echo "Open and read file"
25379         cat $dom > /dev/null
25380         local num=$(get_mdc_stats $mdtidx ost_read)
25381         local ra=$(get_mdc_stats $mdtidx req_active)
25382         local rw=$(get_mdc_stats $mdtidx req_waittime)
25383
25384         [ -z $num ] || error "$num READ RPC occured"
25385         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25386         echo "... DONE"
25387
25388         # compare content
25389         cmp $tmp $dom || error "file miscompare"
25390
25391         return 0
25392 }
25393 run_test 271d "DoM: read on open (1K file in reply buffer)"
25394
25395 test_271f() {
25396         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25397                 skip "Need MDS version at least 2.10.57"
25398
25399         local dom=$DIR/$tdir/dom
25400         local tmp=$TMP/$tfile
25401         trap "cleanup_271def_tests $tmp" EXIT
25402
25403         mkdir -p $DIR/$tdir
25404
25405         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25406
25407         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25408
25409         cancel_lru_locks mdc
25410         dd if=/dev/urandom of=$tmp bs=265000 count=1
25411         dd if=$tmp of=$dom bs=265000 count=1
25412         cancel_lru_locks mdc
25413         cat /etc/hosts >> $tmp
25414         lctl set_param -n mdc.*.stats=clear
25415
25416         echo "Append to the same page"
25417         cat /etc/hosts >> $dom
25418         local num=$(get_mdc_stats $mdtidx ost_read)
25419         local ra=$(get_mdc_stats $mdtidx req_active)
25420         local rw=$(get_mdc_stats $mdtidx req_waittime)
25421
25422         [ -z $num ] || error "$num READ RPC occured"
25423         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25424         echo "... DONE"
25425
25426         # compare content
25427         cmp $tmp $dom || error "file miscompare"
25428
25429         cancel_lru_locks mdc
25430         lctl set_param -n mdc.*.stats=clear
25431
25432         echo "Open and read file"
25433         cat $dom > /dev/null
25434         local num=$(get_mdc_stats $mdtidx ost_read)
25435         local ra=$(get_mdc_stats $mdtidx req_active)
25436         local rw=$(get_mdc_stats $mdtidx req_waittime)
25437
25438         [ -z $num ] && num=0
25439         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25440         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25441         echo "... DONE"
25442
25443         # compare content
25444         cmp $tmp $dom || error "file miscompare"
25445
25446         return 0
25447 }
25448 run_test 271f "DoM: read on open (200K file and read tail)"
25449
25450 test_271g() {
25451         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25452                 skip "Skipping due to old client or server version"
25453
25454         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25455         # to get layout
25456         $CHECKSTAT -t file $DIR1/$tfile
25457
25458         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25459         MULTIOP_PID=$!
25460         sleep 1
25461         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25462         $LCTL set_param fail_loc=0x80000314
25463         rm $DIR1/$tfile || error "Unlink fails"
25464         RC=$?
25465         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25466         [ $RC -eq 0 ] || error "Failed write to stale object"
25467 }
25468 run_test 271g "Discard DoM data vs client flush race"
25469
25470 test_272a() {
25471         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25472                 skip "Need MDS version at least 2.11.50"
25473
25474         local dom=$DIR/$tdir/dom
25475         mkdir -p $DIR/$tdir
25476
25477         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25478         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25479                 error "failed to write data into $dom"
25480         local old_md5=$(md5sum $dom)
25481
25482         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25483                 error "failed to migrate to the same DoM component"
25484
25485         local new_md5=$(md5sum $dom)
25486
25487         [ "$old_md5" == "$new_md5" ] ||
25488                 error "md5sum differ: $old_md5, $new_md5"
25489
25490         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25491                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25492 }
25493 run_test 272a "DoM migration: new layout with the same DOM component"
25494
25495 test_272b() {
25496         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25497                 skip "Need MDS version at least 2.11.50"
25498
25499         local dom=$DIR/$tdir/dom
25500         mkdir -p $DIR/$tdir
25501         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25502         stack_trap "rm -rf $DIR/$tdir"
25503
25504         local mdtidx=$($LFS getstripe -m $dom)
25505         local mdtname=MDT$(printf %04x $mdtidx)
25506         local facet=mds$((mdtidx + 1))
25507
25508         local mdtfree1=$(do_facet $facet \
25509                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25510         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25511                 error "failed to write data into $dom"
25512         local old_md5=$(md5sum $dom)
25513         cancel_lru_locks mdc
25514         local mdtfree1=$(do_facet $facet \
25515                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25516
25517         $LFS migrate -c2 $dom ||
25518                 error "failed to migrate to the new composite layout"
25519         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25520                 error "MDT stripe was not removed"
25521         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25522                 error "$dir1 shouldn't have DATAVER EA"
25523
25524         cancel_lru_locks mdc
25525         local new_md5=$(md5sum $dom)
25526         [ "$old_md5" == "$new_md5" ] ||
25527                 error "$old_md5 != $new_md5"
25528
25529         # Skip free space checks with ZFS
25530         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25531                 local mdtfree2=$(do_facet $facet \
25532                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25533                 [ $mdtfree2 -gt $mdtfree1 ] ||
25534                         error "MDT space is not freed after migration"
25535         fi
25536         return 0
25537 }
25538 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25539
25540 test_272c() {
25541         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25542                 skip "Need MDS version at least 2.11.50"
25543
25544         local dom=$DIR/$tdir/$tfile
25545         mkdir -p $DIR/$tdir
25546         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25547         stack_trap "rm -rf $DIR/$tdir"
25548
25549         local mdtidx=$($LFS getstripe -m $dom)
25550         local mdtname=MDT$(printf %04x $mdtidx)
25551         local facet=mds$((mdtidx + 1))
25552
25553         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25554                 error "failed to write data into $dom"
25555         local old_md5=$(md5sum $dom)
25556         cancel_lru_locks mdc
25557         local mdtfree1=$(do_facet $facet \
25558                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25559
25560         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25561                 error "failed to migrate to the new composite layout"
25562         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25563                 error "MDT stripe was not removed"
25564
25565         cancel_lru_locks mdc
25566         local new_md5=$(md5sum $dom)
25567         [ "$old_md5" == "$new_md5" ] ||
25568                 error "$old_md5 != $new_md5"
25569
25570         # Skip free space checks with ZFS
25571         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25572                 local mdtfree2=$(do_facet $facet \
25573                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25574                 [ $mdtfree2 -gt $mdtfree1 ] ||
25575                         error "MDS space is not freed after migration"
25576         fi
25577         return 0
25578 }
25579 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25580
25581 test_272d() {
25582         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25583                 skip "Need MDS version at least 2.12.55"
25584
25585         local dom=$DIR/$tdir/$tfile
25586         mkdir -p $DIR/$tdir
25587         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25588
25589         local mdtidx=$($LFS getstripe -m $dom)
25590         local mdtname=MDT$(printf %04x $mdtidx)
25591         local facet=mds$((mdtidx + 1))
25592
25593         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25594                 error "failed to write data into $dom"
25595         local old_md5=$(md5sum $dom)
25596         cancel_lru_locks mdc
25597         local mdtfree1=$(do_facet $facet \
25598                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25599
25600         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25601                 error "failed mirroring to the new composite layout"
25602         $LFS mirror resync $dom ||
25603                 error "failed mirror resync"
25604         $LFS mirror split --mirror-id 1 -d $dom ||
25605                 error "failed mirror split"
25606
25607         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25608                 error "MDT stripe was not removed"
25609
25610         cancel_lru_locks mdc
25611         local new_md5=$(md5sum $dom)
25612         [ "$old_md5" == "$new_md5" ] ||
25613                 error "$old_md5 != $new_md5"
25614
25615         # Skip free space checks with ZFS
25616         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25617                 local mdtfree2=$(do_facet $facet \
25618                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25619                 [ $mdtfree2 -gt $mdtfree1 ] ||
25620                         error "MDS space is not freed after DOM mirror deletion"
25621         fi
25622         return 0
25623 }
25624 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25625
25626 test_272e() {
25627         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25628                 skip "Need MDS version at least 2.12.55"
25629
25630         local dom=$DIR/$tdir/$tfile
25631         mkdir -p $DIR/$tdir
25632         $LFS setstripe -c 2 $dom
25633
25634         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25635                 error "failed to write data into $dom"
25636         local old_md5=$(md5sum $dom)
25637         cancel_lru_locks
25638
25639         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25640                 error "failed mirroring to the DOM layout"
25641         $LFS mirror resync $dom ||
25642                 error "failed mirror resync"
25643         $LFS mirror split --mirror-id 1 -d $dom ||
25644                 error "failed mirror split"
25645
25646         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25647                 error "MDT stripe wasn't set"
25648
25649         cancel_lru_locks
25650         local new_md5=$(md5sum $dom)
25651         [ "$old_md5" == "$new_md5" ] ||
25652                 error "$old_md5 != $new_md5"
25653
25654         return 0
25655 }
25656 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25657
25658 test_272f() {
25659         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25660                 skip "Need MDS version at least 2.12.55"
25661
25662         local dom=$DIR/$tdir/$tfile
25663         mkdir -p $DIR/$tdir
25664         $LFS setstripe -c 2 $dom
25665
25666         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25667                 error "failed to write data into $dom"
25668         local old_md5=$(md5sum $dom)
25669         cancel_lru_locks
25670
25671         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25672                 error "failed migrating to the DOM file"
25673
25674         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25675                 error "MDT stripe wasn't set"
25676
25677         cancel_lru_locks
25678         local new_md5=$(md5sum $dom)
25679         [ "$old_md5" != "$new_md5" ] &&
25680                 error "$old_md5 != $new_md5"
25681
25682         return 0
25683 }
25684 run_test 272f "DoM migration: OST-striped file to DOM file"
25685
25686 test_273a() {
25687         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25688                 skip "Need MDS version at least 2.11.50"
25689
25690         # Layout swap cannot be done if either file has DOM component,
25691         # this will never be supported, migration should be used instead
25692
25693         local dom=$DIR/$tdir/$tfile
25694         mkdir -p $DIR/$tdir
25695
25696         $LFS setstripe -c2 ${dom}_plain
25697         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25698         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25699                 error "can swap layout with DoM component"
25700         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25701                 error "can swap layout with DoM component"
25702
25703         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25704         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25705                 error "can swap layout with DoM component"
25706         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25707                 error "can swap layout with DoM component"
25708         return 0
25709 }
25710 run_test 273a "DoM: layout swapping should fail with DOM"
25711
25712 test_273b() {
25713         mkdir -p $DIR/$tdir
25714         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25715
25716 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25717         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25718
25719         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25720 }
25721 run_test 273b "DoM: race writeback and object destroy"
25722
25723 test_273c() {
25724         mkdir -p $DIR/$tdir
25725         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25726
25727         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25728         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25729
25730         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25731 }
25732 run_test 273c "race writeback and object destroy"
25733
25734 test_275() {
25735         remote_ost_nodsh && skip "remote OST with nodsh"
25736         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25737                 skip "Need OST version >= 2.10.57"
25738
25739         local file=$DIR/$tfile
25740         local oss
25741
25742         oss=$(comma_list $(osts_nodes))
25743
25744         dd if=/dev/urandom of=$file bs=1M count=2 ||
25745                 error "failed to create a file"
25746         stack_trap "rm -f $file"
25747         cancel_lru_locks osc
25748
25749         #lock 1
25750         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25751                 error "failed to read a file"
25752
25753 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25754         $LCTL set_param fail_loc=0x8000031f
25755
25756         cancel_lru_locks osc &
25757         sleep 1
25758
25759 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25760         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25761         #IO takes another lock, but matches the PENDING one
25762         #and places it to the IO RPC
25763         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25764                 error "failed to read a file with PENDING lock"
25765 }
25766 run_test 275 "Read on a canceled duplicate lock"
25767
25768 test_276() {
25769         remote_ost_nodsh && skip "remote OST with nodsh"
25770         local pid
25771
25772         do_facet ost1 "(while true; do \
25773                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25774                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25775         pid=$!
25776
25777         for LOOP in $(seq 20); do
25778                 stop ost1
25779                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25780         done
25781         kill -9 $pid
25782         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25783                 rm $TMP/sanity_276_pid"
25784 }
25785 run_test 276 "Race between mount and obd_statfs"
25786
25787 test_277() {
25788         $LCTL set_param ldlm.namespaces.*.lru_size=0
25789         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25790         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25791                           awk '/^used_mb/ { print $2 }')
25792         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25793         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25794                 oflag=direct conv=notrunc
25795         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25796                     awk '/^used_mb/ { print $2 }')
25797         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25798 }
25799 run_test 277 "Direct IO shall drop page cache"
25800
25801 test_278() {
25802         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25803         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25804         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25805                 skip "needs the same host for mdt1 mdt2" && return
25806
25807         local pid1
25808         local pid2
25809
25810 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25811         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25812         stop mds2 &
25813         pid2=$!
25814
25815         stop mds1
25816
25817         echo "Starting MDTs"
25818         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25819         wait $pid2
25820 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25821 #will return NULL
25822         do_facet mds2 $LCTL set_param fail_loc=0
25823
25824         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25825         wait_recovery_complete mds2
25826 }
25827 run_test 278 "Race starting MDS between MDTs stop/start"
25828
25829 test_280() {
25830         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25831                 skip "Need MGS version at least 2.13.52"
25832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25833         combined_mgs_mds || skip "needs combined MGS/MDT"
25834
25835         umount_client $MOUNT
25836 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25837         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25838
25839         mount_client $MOUNT &
25840         sleep 1
25841         stop mgs || error "stop mgs failed"
25842         #for a race mgs would crash
25843         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25844         # make sure we unmount client before remounting
25845         wait
25846         umount_client $MOUNT
25847         mount_client $MOUNT || error "mount client failed"
25848 }
25849 run_test 280 "Race between MGS umount and client llog processing"
25850
25851 cleanup_test_300() {
25852         trap 0
25853         umask $SAVE_UMASK
25854 }
25855
25856 test_striped_dir() {
25857         local mdt_index=$1
25858         local stripe_count=$2
25859         local overstriping=$3
25860         local stripe_index
25861         local getstripe_count
25862
25863         mkdir -p $DIR/$tdir
25864
25865         SAVE_UMASK=$(umask)
25866         trap cleanup_test_300 RETURN EXIT
25867
25868         if [ -z $overstriping ]; then
25869                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25870                                         -o 755 $DIR/$tdir/striped_dir ||
25871                         error "set striped dir error"
25872         else
25873                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25874                                         -o 755 $DIR/$tdir/striped_dir ||
25875                         error "set striped dir error"
25876         fi
25877
25878         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25879         [ "$mode" = "755" ] || error "expect 755 got $mode"
25880
25881         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25882                 error "getdirstripe failed"
25883         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25884         if [ "$getstripe_count" != "$stripe_count" ]; then
25885                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25886         fi
25887         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25888         if [ "$getstripe_count" != "$stripe_count" ]; then
25889                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25890         fi
25891
25892         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25893         if [ "$stripe_index" != "$mdt_index" ]; then
25894                 error "stripe_index is $stripe_index, expect $mdt_index"
25895         fi
25896
25897         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25898                 error "nlink error after create striped dir"
25899
25900         mkdir $DIR/$tdir/striped_dir/a
25901         mkdir $DIR/$tdir/striped_dir/b
25902
25903         stat $DIR/$tdir/striped_dir/a ||
25904                 error "create dir under striped dir failed"
25905         stat $DIR/$tdir/striped_dir/b ||
25906                 error "create dir under striped dir failed"
25907
25908         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25909                 error "nlink error after mkdir"
25910
25911         rmdir $DIR/$tdir/striped_dir/a
25912         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25913                 error "nlink error after rmdir"
25914
25915         rmdir $DIR/$tdir/striped_dir/b
25916         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25917                 error "nlink error after rmdir"
25918
25919         chattr +i $DIR/$tdir/striped_dir
25920         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25921                 error "immutable flags not working under striped dir!"
25922         chattr -i $DIR/$tdir/striped_dir
25923
25924         rmdir $DIR/$tdir/striped_dir ||
25925                 error "rmdir striped dir error"
25926
25927         cleanup_test_300
25928
25929         true
25930 }
25931
25932 test_300a() {
25933         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25934                 skip "skipped for lustre < 2.7.0"
25935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25936         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25937
25938         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25939         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25940 }
25941 run_test 300a "basic striped dir sanity test"
25942
25943 test_300b() {
25944         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25945                 skip "skipped for lustre < 2.7.0"
25946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25947         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25948
25949         local i
25950         local mtime1
25951         local mtime2
25952         local mtime3
25953
25954         test_mkdir $DIR/$tdir || error "mkdir fail"
25955         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25956                 error "set striped dir error"
25957         for i in {0..9}; do
25958                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25959                 sleep 1
25960                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25961                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25962                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25963                 sleep 1
25964                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25965                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25966                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25967         done
25968         true
25969 }
25970 run_test 300b "check ctime/mtime for striped dir"
25971
25972 test_300c() {
25973         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25974                 skip "skipped for lustre < 2.7.0"
25975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25977
25978         local file_count
25979
25980         mkdir_on_mdt0 $DIR/$tdir
25981         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25982                 error "set striped dir error"
25983
25984         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25985                 error "chown striped dir failed"
25986
25987         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25988                 error "create 5k files failed"
25989
25990         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25991
25992         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25993
25994         rm -rf $DIR/$tdir
25995 }
25996 run_test 300c "chown && check ls under striped directory"
25997
25998 test_300d() {
25999         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26000                 skip "skipped for lustre < 2.7.0"
26001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26002         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26003
26004         local stripe_count
26005         local file
26006
26007         mkdir -p $DIR/$tdir
26008         $LFS setstripe -c 2 $DIR/$tdir
26009
26010         #local striped directory
26011         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26012                 error "set striped dir error"
26013         #look at the directories for debug purposes
26014         ls -l $DIR/$tdir
26015         $LFS getdirstripe $DIR/$tdir
26016         ls -l $DIR/$tdir/striped_dir
26017         $LFS getdirstripe $DIR/$tdir/striped_dir
26018         createmany -o $DIR/$tdir/striped_dir/f 10 ||
26019                 error "create 10 files failed"
26020
26021         #remote striped directory
26022         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
26023                 error "set striped dir error"
26024         #look at the directories for debug purposes
26025         ls -l $DIR/$tdir
26026         $LFS getdirstripe $DIR/$tdir
26027         ls -l $DIR/$tdir/remote_striped_dir
26028         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
26029         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
26030                 error "create 10 files failed"
26031
26032         for file in $(find $DIR/$tdir); do
26033                 stripe_count=$($LFS getstripe -c $file)
26034                 [ $stripe_count -eq 2 ] ||
26035                         error "wrong stripe $stripe_count for $file"
26036         done
26037
26038         rm -rf $DIR/$tdir
26039 }
26040 run_test 300d "check default stripe under striped directory"
26041
26042 test_300e() {
26043         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26044                 skip "Need MDS version at least 2.7.55"
26045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26046         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26047
26048         local stripe_count
26049         local file
26050
26051         mkdir -p $DIR/$tdir
26052
26053         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26054                 error "set striped dir error"
26055
26056         touch $DIR/$tdir/striped_dir/a
26057         touch $DIR/$tdir/striped_dir/b
26058         touch $DIR/$tdir/striped_dir/c
26059
26060         mkdir $DIR/$tdir/striped_dir/dir_a
26061         mkdir $DIR/$tdir/striped_dir/dir_b
26062         mkdir $DIR/$tdir/striped_dir/dir_c
26063
26064         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26065                 error "set striped adir under striped dir error"
26066
26067         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26068                 error "set striped bdir under striped dir error"
26069
26070         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26071                 error "set striped cdir under striped dir error"
26072
26073         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26074                 error "rename dir under striped dir fails"
26075
26076         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26077                 error "rename dir under different stripes fails"
26078
26079         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26080                 error "rename file under striped dir should succeed"
26081
26082         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26083                 error "rename dir under striped dir should succeed"
26084
26085         rm -rf $DIR/$tdir
26086 }
26087 run_test 300e "check rename under striped directory"
26088
26089 test_300f() {
26090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26092         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26093                 skip "Need MDS version at least 2.7.55"
26094
26095         local stripe_count
26096         local file
26097
26098         rm -rf $DIR/$tdir
26099         mkdir -p $DIR/$tdir
26100
26101         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26102                 error "set striped dir error"
26103
26104         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26105                 error "set striped dir error"
26106
26107         touch $DIR/$tdir/striped_dir/a
26108         mkdir $DIR/$tdir/striped_dir/dir_a
26109         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26110                 error "create striped dir under striped dir fails"
26111
26112         touch $DIR/$tdir/striped_dir1/b
26113         mkdir $DIR/$tdir/striped_dir1/dir_b
26114         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26115                 error "create striped dir under striped dir fails"
26116
26117         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26118                 error "rename dir under different striped dir should fail"
26119
26120         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26121                 error "rename striped dir under diff striped dir should fail"
26122
26123         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26124                 error "rename file under diff striped dirs fails"
26125
26126         rm -rf $DIR/$tdir
26127 }
26128 run_test 300f "check rename cross striped directory"
26129
26130 test_300_check_default_striped_dir()
26131 {
26132         local dirname=$1
26133         local default_count=$2
26134         local default_index=$3
26135         local stripe_count
26136         local stripe_index
26137         local dir_stripe_index
26138         local dir
26139
26140         echo "checking $dirname $default_count $default_index"
26141         $LFS setdirstripe -D -c $default_count -i $default_index \
26142                                 -H all_char $DIR/$tdir/$dirname ||
26143                 error "set default stripe on striped dir error"
26144         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26145         [ $stripe_count -eq $default_count ] ||
26146                 error "expect $default_count get $stripe_count for $dirname"
26147
26148         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26149         [ $stripe_index -eq $default_index ] ||
26150                 error "expect $default_index get $stripe_index for $dirname"
26151
26152         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26153                                                 error "create dirs failed"
26154
26155         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26156         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26157         for dir in $(find $DIR/$tdir/$dirname/*); do
26158                 stripe_count=$($LFS getdirstripe -c $dir)
26159                 (( $stripe_count == $default_count )) ||
26160                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26161                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26162                 error "stripe count $default_count != $stripe_count for $dir"
26163
26164                 stripe_index=$($LFS getdirstripe -i $dir)
26165                 [ $default_index -eq -1 ] ||
26166                         [ $stripe_index -eq $default_index ] ||
26167                         error "$stripe_index != $default_index for $dir"
26168
26169                 #check default stripe
26170                 stripe_count=$($LFS getdirstripe -D -c $dir)
26171                 [ $stripe_count -eq $default_count ] ||
26172                 error "default count $default_count != $stripe_count for $dir"
26173
26174                 stripe_index=$($LFS getdirstripe -D -i $dir)
26175                 [ $stripe_index -eq $default_index ] ||
26176                 error "default index $default_index != $stripe_index for $dir"
26177         done
26178         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26179 }
26180
26181 test_300g() {
26182         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26183         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26184                 skip "Need MDS version at least 2.7.55"
26185
26186         local dir
26187         local stripe_count
26188         local stripe_index
26189
26190         mkdir_on_mdt0 $DIR/$tdir
26191         mkdir $DIR/$tdir/normal_dir
26192
26193         #Checking when client cache stripe index
26194         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26195         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26196                 error "create striped_dir failed"
26197
26198         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26199                 error "create dir0 fails"
26200         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26201         [ $stripe_index -eq 0 ] ||
26202                 error "dir0 expect index 0 got $stripe_index"
26203
26204         mkdir $DIR/$tdir/striped_dir/dir1 ||
26205                 error "create dir1 fails"
26206         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26207         [ $stripe_index -eq 1 ] ||
26208                 error "dir1 expect index 1 got $stripe_index"
26209
26210         #check default stripe count/stripe index
26211         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26212         test_300_check_default_striped_dir normal_dir 1 0
26213         test_300_check_default_striped_dir normal_dir -1 1
26214         test_300_check_default_striped_dir normal_dir 2 -1
26215
26216         #delete default stripe information
26217         echo "delete default stripeEA"
26218         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26219                 error "set default stripe on striped dir error"
26220
26221         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26222         for dir in $(find $DIR/$tdir/normal_dir/*); do
26223                 stripe_count=$($LFS getdirstripe -c $dir)
26224                 [ $stripe_count -eq 0 ] ||
26225                         error "expect 1 get $stripe_count for $dir"
26226         done
26227 }
26228 run_test 300g "check default striped directory for normal directory"
26229
26230 test_300h() {
26231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26232         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26233                 skip "Need MDS version at least 2.7.55"
26234
26235         local dir
26236         local stripe_count
26237
26238         mkdir $DIR/$tdir
26239         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26240                 error "set striped dir error"
26241
26242         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26243         test_300_check_default_striped_dir striped_dir 1 0
26244         test_300_check_default_striped_dir striped_dir -1 1
26245         test_300_check_default_striped_dir striped_dir 2 -1
26246
26247         #delete default stripe information
26248         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26249                 error "set default stripe on striped dir error"
26250
26251         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26252         for dir in $(find $DIR/$tdir/striped_dir/*); do
26253                 stripe_count=$($LFS getdirstripe -c $dir)
26254                 [ $stripe_count -eq 0 ] ||
26255                         error "expect 1 get $stripe_count for $dir"
26256         done
26257 }
26258 run_test 300h "check default striped directory for striped directory"
26259
26260 test_300i() {
26261         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26262         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26263         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26264                 skip "Need MDS version at least 2.7.55"
26265
26266         local stripe_count
26267         local file
26268
26269         mkdir $DIR/$tdir
26270
26271         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26272                 error "set striped dir error"
26273
26274         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26275                 error "create files under striped dir failed"
26276
26277         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26278                 error "set striped hashdir error"
26279
26280         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26281                 error "create dir0 under hash dir failed"
26282         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26283                 error "create dir1 under hash dir failed"
26284         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26285                 error "create dir2 under hash dir failed"
26286
26287         # unfortunately, we need to umount to clear dir layout cache for now
26288         # once we fully implement dir layout, we can drop this
26289         umount_client $MOUNT || error "umount failed"
26290         mount_client $MOUNT || error "mount failed"
26291
26292         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26293         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26294         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26295
26296         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26297                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26298                         error "create crush2 dir $tdir/hashdir/d3 failed"
26299                 $LFS find -H crush2 $DIR/$tdir/hashdir
26300                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26301                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26302
26303                 # mkdir with an invalid hash type (hash=fail_val) from client
26304                 # should be replaced on MDS with a valid (default) hash type
26305                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26306                 $LCTL set_param fail_loc=0x1901 fail_val=99
26307                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26308
26309                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26310                 local expect=$(do_facet mds1 \
26311                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26312                 [[ $hash == $expect ]] ||
26313                         error "d99 hash '$hash' != expected hash '$expect'"
26314         fi
26315
26316         #set the stripe to be unknown hash type on read
26317         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26318         $LCTL set_param fail_loc=0x1901 fail_val=99
26319         for ((i = 0; i < 10; i++)); do
26320                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26321                         error "stat f-$i failed"
26322                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26323         done
26324
26325         touch $DIR/$tdir/striped_dir/f0 &&
26326                 error "create under striped dir with unknown hash should fail"
26327
26328         $LCTL set_param fail_loc=0
26329
26330         umount_client $MOUNT || error "umount failed"
26331         mount_client $MOUNT || error "mount failed"
26332
26333         return 0
26334 }
26335 run_test 300i "client handle unknown hash type striped directory"
26336
26337 test_300j() {
26338         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26340         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26341                 skip "Need MDS version at least 2.7.55"
26342
26343         local stripe_count
26344         local file
26345
26346         mkdir $DIR/$tdir
26347
26348         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26349         $LCTL set_param fail_loc=0x1702
26350         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26351                 error "set striped dir error"
26352
26353         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26354                 error "create files under striped dir failed"
26355
26356         $LCTL set_param fail_loc=0
26357
26358         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26359
26360         return 0
26361 }
26362 run_test 300j "test large update record"
26363
26364 test_300k() {
26365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26367         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26368                 skip "Need MDS version at least 2.7.55"
26369
26370         # this test needs a huge transaction
26371         local kb
26372         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26373              osd*.$FSNAME-MDT0000.kbytestotal")
26374         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26375
26376         local stripe_count
26377         local file
26378
26379         mkdir $DIR/$tdir
26380
26381         #define OBD_FAIL_LARGE_STRIPE   0x1703
26382         $LCTL set_param fail_loc=0x1703
26383         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26384                 error "set striped dir error"
26385         $LCTL set_param fail_loc=0
26386
26387         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26388                 error "getstripeddir fails"
26389         rm -rf $DIR/$tdir/striped_dir ||
26390                 error "unlink striped dir fails"
26391
26392         return 0
26393 }
26394 run_test 300k "test large striped directory"
26395
26396 test_300l() {
26397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26399         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26400                 skip "Need MDS version at least 2.7.55"
26401
26402         local stripe_index
26403
26404         test_mkdir -p $DIR/$tdir/striped_dir
26405         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26406                         error "chown $RUNAS_ID failed"
26407         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26408                 error "set default striped dir failed"
26409
26410         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26411         $LCTL set_param fail_loc=0x80000158
26412         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26413
26414         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26415         [ $stripe_index -eq 1 ] ||
26416                 error "expect 1 get $stripe_index for $dir"
26417 }
26418 run_test 300l "non-root user to create dir under striped dir with stale layout"
26419
26420 test_300m() {
26421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26422         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26423         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26424                 skip "Need MDS version at least 2.7.55"
26425
26426         mkdir -p $DIR/$tdir/striped_dir
26427         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26428                 error "set default stripes dir error"
26429
26430         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26431
26432         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26433         [ $stripe_count -eq 0 ] ||
26434                         error "expect 0 get $stripe_count for a"
26435
26436         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26437                 error "set default stripes dir error"
26438
26439         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26440
26441         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26442         [ $stripe_count -eq 0 ] ||
26443                         error "expect 0 get $stripe_count for b"
26444
26445         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26446                 error "set default stripes dir error"
26447
26448         mkdir $DIR/$tdir/striped_dir/c &&
26449                 error "default stripe_index is invalid, mkdir c should fails"
26450
26451         rm -rf $DIR/$tdir || error "rmdir fails"
26452 }
26453 run_test 300m "setstriped directory on single MDT FS"
26454
26455 cleanup_300n() {
26456         local list=$(comma_list $(mdts_nodes))
26457
26458         trap 0
26459         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26460 }
26461
26462 test_300n() {
26463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26465         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26466                 skip "Need MDS version at least 2.7.55"
26467         remote_mds_nodsh && skip "remote MDS with nodsh"
26468
26469         local stripe_index
26470         local list=$(comma_list $(mdts_nodes))
26471
26472         trap cleanup_300n RETURN EXIT
26473         mkdir -p $DIR/$tdir
26474         chmod 777 $DIR/$tdir
26475         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26476                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26477                 error "create striped dir succeeds with gid=0"
26478
26479         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26480         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26481                 error "create striped dir fails with gid=-1"
26482
26483         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26484         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26485                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26486                 error "set default striped dir succeeds with gid=0"
26487
26488
26489         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26490         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26491                 error "set default striped dir fails with gid=-1"
26492
26493
26494         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26495         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26496                                         error "create test_dir fails"
26497         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26498                                         error "create test_dir1 fails"
26499         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26500                                         error "create test_dir2 fails"
26501         cleanup_300n
26502 }
26503 run_test 300n "non-root user to create dir under striped dir with default EA"
26504
26505 test_300o() {
26506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26508         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26509                 skip "Need MDS version at least 2.7.55"
26510
26511         local numfree1
26512         local numfree2
26513
26514         mkdir -p $DIR/$tdir
26515
26516         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26517         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26518         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26519                 skip "not enough free inodes $numfree1 $numfree2"
26520         fi
26521
26522         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26523         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26524         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26525                 skip "not enough free space $numfree1 $numfree2"
26526         fi
26527
26528         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26529                 error "setdirstripe fails"
26530
26531         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26532                 error "create dirs fails"
26533
26534         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26535         ls $DIR/$tdir/striped_dir > /dev/null ||
26536                 error "ls striped dir fails"
26537         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26538                 error "unlink big striped dir fails"
26539 }
26540 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26541
26542 test_300p() {
26543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26545         remote_mds_nodsh && skip "remote MDS with nodsh"
26546
26547         mkdir_on_mdt0 $DIR/$tdir
26548
26549         #define OBD_FAIL_OUT_ENOSPC     0x1704
26550         do_facet mds2 lctl set_param fail_loc=0x80001704
26551         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26552                  && error "create striped directory should fail"
26553
26554         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26555
26556         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26557         true
26558 }
26559 run_test 300p "create striped directory without space"
26560
26561 test_300q() {
26562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26564
26565         local fd=$(free_fd)
26566         local cmd="exec $fd<$tdir"
26567         cd $DIR
26568         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26569         eval $cmd
26570         cmd="exec $fd<&-"
26571         trap "eval $cmd" EXIT
26572         cd $tdir || error "cd $tdir fails"
26573         rmdir  ../$tdir || error "rmdir $tdir fails"
26574         mkdir local_dir && error "create dir succeeds"
26575         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26576         eval $cmd
26577         return 0
26578 }
26579 run_test 300q "create remote directory under orphan directory"
26580
26581 test_300r() {
26582         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26583                 skip "Need MDS version at least 2.7.55" && return
26584         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26585
26586         mkdir $DIR/$tdir
26587
26588         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26589                 error "set striped dir error"
26590
26591         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26592                 error "getstripeddir fails"
26593
26594         local stripe_count
26595         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26596                       awk '/lmv_stripe_count:/ { print $2 }')
26597
26598         [ $MDSCOUNT -ne $stripe_count ] &&
26599                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26600
26601         rm -rf $DIR/$tdir/striped_dir ||
26602                 error "unlink striped dir fails"
26603 }
26604 run_test 300r "test -1 striped directory"
26605
26606 test_300s_helper() {
26607         local count=$1
26608
26609         local stripe_dir=$DIR/$tdir/striped_dir.$count
26610
26611         $LFS mkdir -c $count $stripe_dir ||
26612                 error "lfs mkdir -c error"
26613
26614         $LFS getdirstripe $stripe_dir ||
26615                 error "lfs getdirstripe fails"
26616
26617         local stripe_count
26618         stripe_count=$($LFS getdirstripe $stripe_dir |
26619                       awk '/lmv_stripe_count:/ { print $2 }')
26620
26621         [ $count -ne $stripe_count ] &&
26622                 error_noexit "bad stripe count $stripe_count expected $count"
26623
26624         local dupe_stripes
26625         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26626                 awk '/0x/ {count[$1] += 1}; END {
26627                         for (idx in count) {
26628                                 if (count[idx]>1) {
26629                                         print "index " idx " count " count[idx]
26630                                 }
26631                         }
26632                 }')
26633
26634         if [[ -n "$dupe_stripes" ]] ; then
26635                 lfs getdirstripe $stripe_dir
26636                 error_noexit "Dupe MDT above: $dupe_stripes "
26637         fi
26638
26639         rm -rf $stripe_dir ||
26640                 error_noexit "unlink $stripe_dir fails"
26641 }
26642
26643 test_300s() {
26644         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26645                 skip "Need MDS version at least 2.7.55" && return
26646         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26647
26648         mkdir $DIR/$tdir
26649         for count in $(seq 2 $MDSCOUNT); do
26650                 test_300s_helper $count
26651         done
26652 }
26653 run_test 300s "test lfs mkdir -c without -i"
26654
26655 test_300t() {
26656         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26657                 skip "need MDS 2.14.55 or later"
26658         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26659
26660         local testdir="$DIR/$tdir/striped_dir"
26661         local dir1=$testdir/dir1
26662         local dir2=$testdir/dir2
26663
26664         mkdir -p $testdir
26665
26666         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26667                 error "failed to set default stripe count for $testdir"
26668
26669         mkdir $dir1
26670         local stripe_count=$($LFS getdirstripe -c $dir1)
26671
26672         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26673
26674         local max_count=$((MDSCOUNT - 1))
26675         local mdts=$(comma_list $(mdts_nodes))
26676
26677         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26678         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26679
26680         mkdir $dir2
26681         stripe_count=$($LFS getdirstripe -c $dir2)
26682
26683         (( $stripe_count == $max_count )) || error "wrong stripe count"
26684 }
26685 run_test 300t "test max_mdt_stripecount"
26686
26687 MDT_OVSTRP_VER="2.15.60"
26688 # 300u family tests MDT overstriping
26689 test_300ua() {
26690         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26691
26692         local setcount=$((MDSCOUNT * 2))
26693
26694         local expected_count
26695
26696         mkdir $DIR/$tdir
26697         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26698                 error "(0) failed basic overstriped dir creation test"
26699         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26700
26701         # This does a basic interop test - if the MDS does not support mdt
26702         # overstriping, we should get stripes == number of MDTs
26703         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26704                 expected_count=$MDSCOUNT
26705         else
26706                 expected_count=$setcount
26707         fi
26708         (( getstripe_count == expected_count )) ||
26709                 error "(1) incorrect stripe count for simple overstriped dir"
26710
26711         rm -rf $DIR/$tdir/${tdir}.0 ||
26712                 error "(2) unable to rm overstriped dir"
26713
26714         # Tests after this require overstriping support
26715         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26716                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26717
26718         test_striped_dir 0 $setcount true ||
26719                 error "(3)failed on overstriped dir"
26720         test_striped_dir 1 $setcount true ||
26721                 error "(4)failed on overstriped dir"
26722
26723         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26724
26725         test_striped_dir 0 $setcount true ||
26726                 error "(5)failed on overstriped dir"
26727 }
26728 run_test 300ua "basic overstriped dir sanity test"
26729
26730 test_300ub() {
26731         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26732                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26733         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26734
26735         mkdir $DIR/$tdir
26736
26737         echo "Testing invalid stripe count, failure expected"
26738         local setcount=$((MDSCOUNT * 2))
26739
26740         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26741         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26742
26743         (( getstripe_count <= MDSCOUNT )) ||
26744                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26745
26746         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26747         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26748         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26749
26750         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26751
26752         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26753         (( getstripe_count == maxcount )) ||
26754                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26755
26756         # Test specific striping with -i
26757         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26758
26759         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26760         (( getstripe_count == 4 )) ||
26761                 error "(2)stripe_count is $getstripe_count, expect 4"
26762
26763         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26764                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26765
26766         [[ -n "$nonzeroindices" ]] ||
26767                 error "(3) stripes indices not all 0: $nonzeroindices"
26768
26769         # Test specific striping with too many stripes on one MDT
26770         echo "Testing invalid striping, failure expected"
26771         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26772         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26773         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26774                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26775         echo "stripes on MDT0: $getstripe_count"
26776         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26777                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26778
26779         setcount=$((MDSCOUNT * 2))
26780         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26781                 error "(5) can't setdirstripe with manually set hash function"
26782
26783         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26784         (( getstripe_count == setcount )) ||
26785                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26786
26787         setcount=$((MDSCOUNT * 2))
26788         mkdir $DIR/${tdir}.5
26789         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26790                 error "(7) can't setdirstripe with manually set hash function"
26791         mkdir $DIR/${tdir}.5/${tdir}.6
26792
26793         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26794         (( getstripe_count == setcount )) ||
26795                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26796 }
26797 run_test 300ub "test MDT overstriping interface & limits"
26798
26799 test_300uc() {
26800         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26801                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26802         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26803
26804         mkdir $DIR/$tdir
26805
26806         local setcount=$((MDSCOUNT * 2))
26807
26808         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26809
26810         mkdir $DIR/$tdir/${tdir}.1
26811
26812         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26813
26814         (( getstripe_count == setcount )) ||
26815                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26816
26817         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26818
26819         local getstripe_count=$($LFS getdirstripe -c \
26820                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26821
26822         (( getstripe_count == setcount )) ||
26823                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26824 }
26825 run_test 300uc "test MDT overstriping as default & inheritance"
26826
26827 test_300ud() {
26828         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26829                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26830         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26831
26832         local mdts=$(comma_list $(mdts_nodes))
26833         local timeout=100
26834
26835         local restripe_status
26836         local delta
26837         local i
26838
26839         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26840
26841         # in case "crush" hash type is not set
26842         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26843
26844         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26845                            mdt.*MDT0000.enable_dir_restripe)
26846         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26847         stack_trap "do_nodes $mdts $LCTL set_param \
26848                     mdt.*.enable_dir_restripe=$restripe_status"
26849
26850         mkdir $DIR/$tdir
26851         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26852                 error "create files under remote dir failed $i"
26853         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26854                 error "create dirs under remote dir failed $i"
26855
26856         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26857
26858         (( setcount < 13 )) || setcount=12
26859         for i in $(seq 2 $setcount); do
26860                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26861                 $LFS setdirstripe -C $i $DIR/$tdir ||
26862                         error "split -C $i $tdir failed"
26863                 wait_update $HOSTNAME \
26864                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26865                         error "dir split not finished"
26866                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26867                         awk '/migrate/ {sum += $2} END { print sum }')
26868                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26869                 # delta is around total_files/stripe_count, deviation 3%
26870                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26871                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26872         done
26873 }
26874 run_test 300ud "dir split"
26875
26876 test_300ue() {
26877         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26878                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26879         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26880
26881         local mdts=$(comma_list $(mdts_nodes))
26882         local timeout=100
26883
26884         local restripe_status
26885         local delta
26886         local c
26887
26888         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26889
26890         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26891
26892         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26893                            mdt.*MDT0000.enable_dir_restripe)
26894         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26895         stack_trap "do_nodes $mdts $LCTL set_param \
26896                     mdt.*.enable_dir_restripe=$restripe_status"
26897
26898         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26899
26900         (( setcount < 13 )) || setcount=12
26901         test_mkdir -C $setcount -H crush $DIR/$tdir
26902         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26903                 error "create files under remote dir failed"
26904         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26905                 error "create dirs under remote dir failed"
26906
26907         for c in $(seq $((setcount - 1)) -1 1); do
26908                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26909                 $LFS setdirstripe -C $c $DIR/$tdir ||
26910                         error "split -C $c $tdir failed"
26911                 wait_update $HOSTNAME \
26912                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26913                         error "dir merge not finished"
26914                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26915                         awk '/migrate/ {sum += $2} END { print sum }')
26916                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26917                 # delta is around total_files/stripe_count, deviation 3%
26918                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26919                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26920         done
26921 }
26922 run_test 300ue "dir merge"
26923
26924 test_300uf() {
26925         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26926                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26927         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26928
26929         # maximum amount of local locks:
26930         # parent striped dir - 2 locks
26931         # new stripe in parent to migrate to - 1 lock
26932         # source and target - 2 locks
26933         # Total 5 locks for regular file
26934         #
26935         # NB: Overstriping should add several extra local locks
26936         # FIXME: Remove this once understood
26937         #lctl set_param *debug=-1 debug_mb=10000
26938         lctl clear
26939         lctl mark "touch/create"
26940         mkdir -p $DIR/$tdir
26941         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26942         local setcount=$((MDSCOUNT * 5))
26943
26944         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26945         touch $DIR/$tdir/dir1/eee
26946
26947         lctl mark "hardlinks"
26948         # create 4 hardlink for 4 more locks
26949         # Total: 9 locks > RS_MAX_LOCKS (8)
26950         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26951         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26952         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26953         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26954         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26955         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26956         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26957         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26958
26959         lctl mark "cancel lru"
26960         cancel_lru_locks mdc
26961
26962         lctl mark "migrate"
26963         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26964                 error "migrate dir fails"
26965
26966         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26967 }
26968 run_test 300uf "migrate with too many local locks"
26969
26970 test_300ug() {
26971         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26972                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26973         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26974
26975         mkdir -p $DIR/$tdir
26976         local migrate_dir=$DIR/$tdir/migrate_dir
26977         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26978         local setcount2=$((setcount - 2))
26979
26980         $LFS setdirstripe -c 2 $migrate_dir ||
26981                 error "(0) failed to create striped directory"
26982
26983         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26984                 error "(1)failed to migrate to overstriped directory"
26985         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26986
26987         (( getstripe_count == setcount )) ||
26988                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26989         touch $DIR/$tdir/migrate_dir/$tfile ||
26990                 error "(3)failed to create file in overstriped directory"
26991         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26992                 error "(4)failed to migrate overstriped directory"
26993         # Check stripe count after migration
26994         $LFS getdirstripe $migrate_dir
26995         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26996         (( getstripe_count == setcount2 )) ||
26997                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26998
26999         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
27000 }
27001 run_test 300ug "migrate overstriped dirs"
27002
27003 prepare_remote_file() {
27004         mkdir $DIR/$tdir/src_dir ||
27005                 error "create remote source failed"
27006
27007         cp /etc/hosts $DIR/$tdir/src_dir/a ||
27008                  error "cp to remote source failed"
27009         touch $DIR/$tdir/src_dir/a
27010
27011         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
27012                 error "create remote target dir failed"
27013
27014         touch $DIR/$tdir/tgt_dir/b
27015
27016         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
27017                 error "rename dir cross MDT failed!"
27018
27019         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
27020                 error "src_child still exists after rename"
27021
27022         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
27023                 error "missing file(a) after rename"
27024
27025         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
27026                 error "diff after rename"
27027 }
27028
27029 test_310a() {
27030         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27032
27033         local remote_file=$DIR/$tdir/tgt_dir/b
27034
27035         mkdir -p $DIR/$tdir
27036
27037         prepare_remote_file || error "prepare remote file failed"
27038
27039         #open-unlink file
27040         $OPENUNLINK $remote_file $remote_file ||
27041                 error "openunlink $remote_file failed"
27042         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27043 }
27044 run_test 310a "open unlink remote file"
27045
27046 test_310b() {
27047         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27049
27050         local remote_file=$DIR/$tdir/tgt_dir/b
27051
27052         mkdir -p $DIR/$tdir
27053
27054         prepare_remote_file || error "prepare remote file failed"
27055
27056         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27057         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27058         $CHECKSTAT -t file $remote_file || error "check file failed"
27059 }
27060 run_test 310b "unlink remote file with multiple links while open"
27061
27062 test_310c() {
27063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27064         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27065
27066         local remote_file=$DIR/$tdir/tgt_dir/b
27067
27068         mkdir -p $DIR/$tdir
27069
27070         prepare_remote_file || error "prepare remote file failed"
27071
27072         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27073         multiop_bg_pause $remote_file O_uc ||
27074                         error "mulitop failed for remote file"
27075         MULTIPID=$!
27076         $MULTIOP $DIR/$tfile Ouc
27077         kill -USR1 $MULTIPID
27078         wait $MULTIPID
27079 }
27080 run_test 310c "open-unlink remote file with multiple links"
27081
27082 #LU-4825
27083 test_311() {
27084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27085         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27086         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27087                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27088         remote_mds_nodsh && skip "remote MDS with nodsh"
27089
27090         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27091         local mdts=$(comma_list $(mdts_nodes))
27092
27093         mkdir -p $DIR/$tdir
27094         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27095         createmany -o $DIR/$tdir/$tfile. 1000
27096
27097         # statfs data is not real time, let's just calculate it
27098         old_iused=$((old_iused + 1000))
27099
27100         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27101                         osp.*OST0000*MDT0000.create_count")
27102         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27103                                 osp.*OST0000*MDT0000.max_create_count")
27104         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27105
27106         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27107         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27108         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27109
27110         unlinkmany $DIR/$tdir/$tfile. 1000
27111
27112         do_nodes $mdts "$LCTL set_param -n \
27113                         osp.*OST0000*.max_create_count=$max_count"
27114         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27115                 do_nodes $mdts "$LCTL set_param -n \
27116                                 osp.*OST0000*.create_count=$count"
27117         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27118                         grep "=0" && error "create_count is zero"
27119
27120         local new_iused
27121         for i in $(seq 120); do
27122                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27123                 # system may be too busy to destroy all objs in time, use
27124                 # a somewhat small value to not fail autotest
27125                 [ $((old_iused - new_iused)) -gt 400 ] && break
27126                 sleep 1
27127         done
27128
27129         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27130         [ $((old_iused - new_iused)) -gt 400 ] ||
27131                 error "objs not destroyed after unlink"
27132 }
27133 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27134
27135 zfs_get_objid()
27136 {
27137         local ost=$1
27138         local tf=$2
27139         local fid=($($LFS getstripe $tf | grep 0x))
27140         local seq=${fid[3]#0x}
27141         local objid=${fid[1]}
27142
27143         local vdevdir=$(dirname $(facet_vdevice $ost))
27144         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27145         local zfs_zapid=$(do_facet $ost $cmd |
27146                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27147                           awk '/Object/{getline; print $1}')
27148         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27149                           awk "/$objid = /"'{printf $3}')
27150
27151         echo $zfs_objid
27152 }
27153
27154 zfs_object_blksz() {
27155         local ost=$1
27156         local objid=$2
27157
27158         local vdevdir=$(dirname $(facet_vdevice $ost))
27159         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27160         local blksz=$(do_facet $ost $cmd $objid |
27161                       awk '/dblk/{getline; printf $4}')
27162
27163         case "${blksz: -1}" in
27164                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27165                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27166                 *) ;;
27167         esac
27168
27169         echo $blksz
27170 }
27171
27172 test_312() { # LU-4856
27173         remote_ost_nodsh && skip "remote OST with nodsh"
27174         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27175
27176         local max_blksz=$(do_facet ost1 \
27177                           $ZFS get -p recordsize $(facet_device ost1) |
27178                           awk '!/VALUE/{print $3}')
27179         local tf=$DIR/$tfile
27180
27181         $LFS setstripe -c1 $tf
27182         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27183
27184         # Get ZFS object id
27185         local zfs_objid=$(zfs_get_objid $facet $tf)
27186         # block size change by sequential overwrite
27187         local bs
27188
27189         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27190                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27191
27192                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27193                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27194         done
27195         rm -f $tf
27196
27197         $LFS setstripe -c1 $tf
27198         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27199
27200         # block size change by sequential append write
27201         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27202         zfs_objid=$(zfs_get_objid $facet $tf)
27203         local count
27204
27205         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27206                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27207                         oflag=sync conv=notrunc
27208
27209                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27210                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27211                         error "blksz error, actual $blksz, " \
27212                                 "expected: 2 * $count * $PAGE_SIZE"
27213         done
27214         rm -f $tf
27215
27216         # random write
27217         $LFS setstripe -c1 $tf
27218         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27219         zfs_objid=$(zfs_get_objid $facet $tf)
27220
27221         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27222         blksz=$(zfs_object_blksz $facet $zfs_objid)
27223         (( blksz == PAGE_SIZE )) ||
27224                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27225
27226         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27227         blksz=$(zfs_object_blksz $facet $zfs_objid)
27228         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27229
27230         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27231         blksz=$(zfs_object_blksz $facet $zfs_objid)
27232         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27233 }
27234 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27235
27236 test_313() {
27237         remote_ost_nodsh && skip "remote OST with nodsh"
27238
27239         local file=$DIR/$tfile
27240
27241         rm -f $file
27242         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27243
27244         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27245         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27246         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27247                 error "write should failed"
27248         do_facet ost1 "$LCTL set_param fail_loc=0"
27249         rm -f $file
27250 }
27251 run_test 313 "io should fail after last_rcvd update fail"
27252
27253 test_314() {
27254         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27255
27256         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27257         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27258         rm -f $DIR/$tfile
27259         wait_delete_completed
27260         do_facet ost1 "$LCTL set_param fail_loc=0"
27261 }
27262 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27263
27264 test_315() { # LU-618
27265         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27266
27267         local file=$DIR/$tfile
27268         rm -f $file
27269
27270         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27271                 error "multiop file write failed"
27272         $MULTIOP $file oO_RDONLY:r4063232_c &
27273         PID=$!
27274
27275         sleep 2
27276
27277         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27278         kill -USR1 $PID
27279
27280         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27281         rm -f $file
27282 }
27283 run_test 315 "read should be accounted"
27284
27285 test_316() {
27286         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27287         large_xattr_enabled || skip "ea_inode feature disabled"
27288
27289         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27290         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27291         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27292         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27293
27294         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27295 }
27296 run_test 316 "lfs migrate of file with large_xattr enabled"
27297
27298 test_317() {
27299         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27300                 skip "Need MDS version at least 2.11.53"
27301         if [ "$ost1_FSTYPE" == "zfs" ]; then
27302                 skip "LU-10370: no implementation for ZFS"
27303         fi
27304
27305         local trunc_sz
27306         local grant_blk_size
27307
27308         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27309                         awk '/grant_block_size:/ { print $2; exit; }')
27310         #
27311         # Create File of size 5M. Truncate it to below size's and verify
27312         # blocks count.
27313         #
27314         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27315                 error "Create file $DIR/$tfile failed"
27316         stack_trap "rm -f $DIR/$tfile" EXIT
27317
27318         for trunc_sz in 2097152 4097 4000 509 0; do
27319                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27320                         error "truncate $tfile to $trunc_sz failed"
27321                 local sz=$(stat --format=%s $DIR/$tfile)
27322                 local blk=$(stat --format=%b $DIR/$tfile)
27323                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27324                                      grant_blk_size) * 8))
27325
27326                 if [[ $blk -ne $trunc_blk ]]; then
27327                         $(which stat) $DIR/$tfile
27328                         error "Expected Block $trunc_blk got $blk for $tfile"
27329                 fi
27330
27331                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27332                         error "Expected Size $trunc_sz got $sz for $tfile"
27333         done
27334
27335         #
27336         # sparse file test
27337         # Create file with a hole and write actual 65536 bytes which aligned
27338         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27339         #
27340         local bs=65536
27341         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27342                 error "Create file : $DIR/$tfile"
27343
27344         #
27345         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27346         # blocks. The block count must drop to 8.
27347         #
27348         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27349                 ((bs - grant_blk_size) + 1)))
27350         $TRUNCATE $DIR/$tfile $trunc_sz ||
27351                 error "truncate $tfile to $trunc_sz failed"
27352
27353         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27354         sz=$(stat --format=%s $DIR/$tfile)
27355         blk=$(stat --format=%b $DIR/$tfile)
27356
27357         if [[ $blk -ne $trunc_bsz ]]; then
27358                 $(which stat) $DIR/$tfile
27359                 error "Expected Block $trunc_bsz got $blk for $tfile"
27360         fi
27361
27362         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27363                 error "Expected Size $trunc_sz got $sz for $tfile"
27364 }
27365 run_test 317 "Verify blocks get correctly update after truncate"
27366
27367 test_318() {
27368         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27369         local old_max_active=$($LCTL get_param -n \
27370                             ${llite_name}.max_read_ahead_async_active \
27371                             2>/dev/null)
27372
27373         $LCTL set_param llite.*.max_read_ahead_async_active=256
27374         local max_active=$($LCTL get_param -n \
27375                            ${llite_name}.max_read_ahead_async_active \
27376                            2>/dev/null)
27377         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27378
27379         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27380                 error "set max_read_ahead_async_active should succeed"
27381
27382         $LCTL set_param llite.*.max_read_ahead_async_active=512
27383         max_active=$($LCTL get_param -n \
27384                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27385         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27386
27387         # restore @max_active
27388         [ $old_max_active -ne 0 ] && $LCTL set_param \
27389                 llite.*.max_read_ahead_async_active=$old_max_active
27390
27391         local old_threshold=$($LCTL get_param -n \
27392                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27393         local max_per_file_mb=$($LCTL get_param -n \
27394                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27395
27396         local invalid=$(($max_per_file_mb + 1))
27397         $LCTL set_param \
27398                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27399                         && error "set $invalid should fail"
27400
27401         local valid=$(($invalid - 1))
27402         $LCTL set_param \
27403                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27404                         error "set $valid should succeed"
27405         local threshold=$($LCTL get_param -n \
27406                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27407         [ $threshold -eq $valid ] || error \
27408                 "expect threshold $valid got $threshold"
27409         $LCTL set_param \
27410                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27411 }
27412 run_test 318 "Verify async readahead tunables"
27413
27414 test_319() {
27415         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27416
27417         local before=$(date +%s)
27418         local evict
27419         local mdir=$DIR/$tdir
27420         local file=$mdir/xxx
27421
27422         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27423         touch $file
27424
27425 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27426         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27427         $LFS migrate -m1 $mdir &
27428
27429         sleep 1
27430         dd if=$file of=/dev/null
27431         wait
27432         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27433           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27434
27435         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27436 }
27437 run_test 319 "lost lease lock on migrate error"
27438
27439 test_350() {
27440         local mdts=$(comma_list $(mdts_nodes))
27441
27442         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27443         stack_trap "rm -r $DIR/$tdir"
27444
27445         #force 1/100 of replies to take "NID mismatch" codepath
27446         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27447         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27448
27449         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27450         stack_trap "killall -9 ls || killall -9 ls"
27451
27452         cp -a /etc $DIR/$tdir || error "cp failed"
27453 }
27454 run_test 350 "force NID mismatch path to be exercised"
27455
27456 test_360() {
27457         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27458                 skip "Need OST version at least 2.15.58.96"
27459         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27460
27461         check_set_fallocate_or_skip
27462         local param="osd-ldiskfs.delayed_unlink_mb"
27463         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27464
27465         do_facet ost1 "$LCTL set_param $param=1MiB"
27466         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27467
27468         mkdir $DIR/$tdir/
27469         do_facet ost1 $LCTL set_param debug=+inode
27470         do_facet ost1 $LCTL clear
27471         local files=100
27472
27473         for ((i = 0; i < $files; i++)); do
27474                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27475                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27476         done
27477         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27478
27479         for ((i = 0; i < $files; i++)); do
27480                 unlink $DIR/$tdir/$tfile.$i ||
27481                         error "unlink $DIR/$tdir/$tfile.$i failed"
27482         done
27483
27484         local count=0
27485         local loop
27486
27487         for (( loop = 0; loop < 30 && count < min; loop++)); do
27488                 sleep 1
27489                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27490                 echo "Count[$loop]: $count"
27491         done
27492         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27493 }
27494 run_test 360 "ldiskfs unlink in a separate thread"
27495
27496 test_398a() { # LU-4198
27497         local ost1_imp=$(get_osc_import_name client ost1)
27498         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27499                          cut -d'.' -f2)
27500
27501         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27502         stack_trap "rm -f $DIR/$tfile"
27503         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27504
27505         # request a new lock on client
27506         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27507
27508         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27509         local lock_count=$($LCTL get_param -n \
27510                            ldlm.namespaces.$imp_name.lru_size)
27511         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27512
27513         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27514
27515         # no lock cached, should use lockless DIO and not enqueue new lock
27516         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27517         lock_count=$($LCTL get_param -n \
27518                      ldlm.namespaces.$imp_name.lru_size)
27519         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27520
27521         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27522
27523         # no lock cached, should use locked DIO append
27524         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27525                 conv=notrunc || error "DIO append failed"
27526         lock_count=$($LCTL get_param -n \
27527                      ldlm.namespaces.$imp_name.lru_size)
27528         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27529 }
27530 run_test 398a "direct IO should cancel lock otherwise lockless"
27531
27532 test_398b() { # LU-4198
27533         local before=$(date +%s)
27534         local njobs=4
27535         local size=48
27536
27537         which fio || skip_env "no fio installed"
27538         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27539         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27540
27541         # Single page, multiple pages, stripe size, 4*stripe size
27542         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27543                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27544                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27545                         --numjobs=$njobs --fallocate=none \
27546                         --iodepth=16 --allow_file_create=0 \
27547                         --size=$((size/njobs))M \
27548                         --filename=$DIR/$tfile &
27549                 bg_pid=$!
27550
27551                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27552                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27553                         --numjobs=$njobs --fallocate=none \
27554                         --iodepth=16 --allow_file_create=0 \
27555                         --size=$((size/njobs))M \
27556                         --filename=$DIR/$tfile || true
27557                 wait $bg_pid
27558         done
27559
27560         evict=$(do_facet client $LCTL get_param \
27561                 osc.$FSNAME-OST*-osc-*/state |
27562             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27563
27564         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27565                 (do_facet client $LCTL get_param \
27566                         osc.$FSNAME-OST*-osc-*/state;
27567                     error "eviction happened: $evict before:$before")
27568
27569         rm -f $DIR/$tfile
27570 }
27571 run_test 398b "DIO and buffer IO race"
27572
27573 test_398c() { # LU-4198
27574         local ost1_imp=$(get_osc_import_name client ost1)
27575         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27576                          cut -d'.' -f2)
27577
27578         which fio || skip_env "no fio installed"
27579
27580         saved_debug=$($LCTL get_param -n debug)
27581         $LCTL set_param debug=0
27582
27583         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27584         ((size /= 1024)) # by megabytes
27585         ((size /= 2)) # write half of the OST at most
27586         [ $size -gt 40 ] && size=40 #reduce test time anyway
27587
27588         $LFS setstripe -c 1 $DIR/$tfile
27589
27590         # it seems like ldiskfs reserves more space than necessary if the
27591         # writing blocks are not mapped, so it extends the file firstly
27592         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27593         cancel_lru_locks osc
27594
27595         # clear and verify rpc_stats later
27596         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27597
27598         local njobs=4
27599         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27600         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27601                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27602                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27603                 --filename=$DIR/$tfile
27604         [ $? -eq 0 ] || error "fio write error"
27605
27606         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27607                 error "Locks were requested while doing AIO"
27608
27609         # get the percentage of 1-page I/O
27610         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27611                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27612                 awk '{print $7}')
27613         (( $pct <= 50 )) || {
27614                 $LCTL get_param osc.${imp_name}.rpc_stats
27615                 error "$pct% of I/O are 1-page"
27616         }
27617
27618         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27619         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27620                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27621                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27622                 --filename=$DIR/$tfile
27623         [ $? -eq 0 ] || error "fio mixed read write error"
27624
27625         echo "AIO with large block size ${size}M"
27626         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27627                 --numjobs=1 --fallocate=none --ioengine=libaio \
27628                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27629                 --filename=$DIR/$tfile
27630         [ $? -eq 0 ] || error "fio large block size failed"
27631
27632         rm -f $DIR/$tfile
27633         $LCTL set_param debug="$saved_debug"
27634 }
27635 run_test 398c "run fio to test AIO"
27636
27637 test_398d() { #  LU-13846
27638         which aiocp || skip_env "no aiocp installed"
27639         local aio_file=$DIR/$tfile.aio
27640
27641         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27642
27643         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27644         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27645         stack_trap "rm -f $DIR/$tfile $aio_file"
27646
27647         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27648
27649         # test memory unaligned aio
27650         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27651                 error "unaligned aio failed"
27652         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27653
27654         rm -f $DIR/$tfile $aio_file
27655 }
27656 run_test 398d "run aiocp to verify block size > stripe size"
27657
27658 test_398e() {
27659         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27660         touch $DIR/$tfile.new
27661         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27662 }
27663 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27664
27665 test_398f() { #  LU-14687
27666         which aiocp || skip_env "no aiocp installed"
27667         local aio_file=$DIR/$tfile.aio
27668
27669         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27670
27671         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27672         stack_trap "rm -f $DIR/$tfile $aio_file"
27673
27674         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27675         $LCTL set_param fail_loc=0x1418
27676         # make sure we don't crash and fail properly
27677         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27678                 error "aio with page allocation failure succeeded"
27679         $LCTL set_param fail_loc=0
27680         diff $DIR/$tfile $aio_file
27681         [[ $? != 0 ]] || error "no diff after failed aiocp"
27682 }
27683 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27684
27685 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27686 # stripe and i/o size must be > stripe size
27687 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27688 # single RPC in flight.  This test shows async DIO submission is working by
27689 # showing multiple RPCs in flight.
27690 test_398g() { #  LU-13798
27691         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27692
27693         # We need to do some i/o first to acquire enough grant to put our RPCs
27694         # in flight; otherwise a new connection may not have enough grant
27695         # available
27696         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27697                 error "parallel dio failed"
27698         stack_trap "rm -f $DIR/$tfile"
27699
27700         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27701         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27702         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27703         stack_trap "$LCTL set_param -n $pages_per_rpc"
27704
27705         # Recreate file so it's empty
27706         rm -f $DIR/$tfile
27707         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27708         #Pause rpc completion to guarantee we see multiple rpcs in flight
27709         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27710         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27711         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27712
27713         # Clear rpc stats
27714         $LCTL set_param osc.*.rpc_stats=c
27715
27716         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27717                 error "parallel dio failed"
27718         stack_trap "rm -f $DIR/$tfile"
27719
27720         $LCTL get_param osc.*-OST0000-*.rpc_stats
27721         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27722                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27723                 grep "8:" | awk '{print $8}')
27724         # We look at the "8 rpcs in flight" field, and verify A) it is present
27725         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27726         # as expected for an 8M DIO to a file with 1M stripes.
27727         # NB: There is occasionally a mystery extra write RPC to a different
27728         # file.  I can't identify why that's happening, so we set up a margin
27729         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27730         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27731
27732         # Verify turning off parallel dio works as expected
27733         # Clear rpc stats
27734         $LCTL set_param osc.*.rpc_stats=c
27735         $LCTL set_param llite.*.parallel_dio=0
27736         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27737
27738         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27739                 error "dio with parallel dio disabled failed"
27740
27741         # Ideally, we would see only one RPC in flight here, but there is an
27742         # unavoidable race between i/o completion and RPC in flight counting,
27743         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27744         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27745         # So instead we just verify it's always < 8.
27746         $LCTL get_param osc.*-OST0000-*.rpc_stats
27747         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27748                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27749                 grep '^$' -B1 | grep . | awk '{print $1}')
27750         [ $ret != "8:" ] ||
27751                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27752 }
27753 run_test 398g "verify parallel dio async RPC submission"
27754
27755 test_398h() { #  LU-13798
27756         local dio_file=$DIR/$tfile.dio
27757
27758         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27759
27760         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27761         stack_trap "rm -f $DIR/$tfile $dio_file"
27762
27763         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27764                 error "parallel dio failed"
27765         diff $DIR/$tfile $dio_file
27766         [[ $? == 0 ]] || error "file diff after aiocp"
27767 }
27768 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27769
27770 test_398i() { #  LU-13798
27771         local dio_file=$DIR/$tfile.dio
27772
27773         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27774
27775         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27776         stack_trap "rm -f $DIR/$tfile $dio_file"
27777
27778         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27779         $LCTL set_param fail_loc=0x1418
27780         # make sure we don't crash and fail properly
27781         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27782                 error "parallel dio page allocation failure succeeded"
27783         diff $DIR/$tfile $dio_file
27784         [[ $? != 0 ]] || error "no diff after failed aiocp"
27785 }
27786 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27787
27788 test_398j() { #  LU-13798
27789         # Stripe size > RPC size but less than i/o size tests split across
27790         # stripes and RPCs for individual i/o op
27791         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27792
27793         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27794         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27795         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27796         stack_trap "$LCTL set_param -n $pages_per_rpc"
27797
27798         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27799                 error "parallel dio write failed"
27800         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27801
27802         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27803                 error "parallel dio read failed"
27804         diff $DIR/$tfile $DIR/$tfile.2
27805         [[ $? == 0 ]] || error "file diff after parallel dio read"
27806 }
27807 run_test 398j "test parallel dio where stripe size > rpc_size"
27808
27809 test_398k() { #  LU-13798
27810         wait_delete_completed
27811         wait_mds_ost_sync
27812
27813         # 4 stripe file; we will cause out of space on OST0
27814         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27815
27816         # Fill OST0 (if it's not too large)
27817         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27818                    head -n1)
27819         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27820                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27821         fi
27822         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27823         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27824                 error "dd should fill OST0"
27825         stack_trap "rm -f $DIR/$tfile.1"
27826
27827         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27828         err=$?
27829
27830         ls -la $DIR/$tfile
27831         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27832                 error "file is not 0 bytes in size"
27833
27834         # dd above should not succeed, but don't error until here so we can
27835         # get debug info above
27836         [[ $err != 0 ]] ||
27837                 error "parallel dio write with enospc succeeded"
27838         stack_trap "rm -f $DIR/$tfile"
27839 }
27840 run_test 398k "test enospc on first stripe"
27841
27842 test_398l() { #  LU-13798
27843         wait_delete_completed
27844         wait_mds_ost_sync
27845
27846         # 4 stripe file; we will cause out of space on OST0
27847         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27848         # happens on the second i/o chunk we issue
27849         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27850
27851         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27852         stack_trap "rm -f $DIR/$tfile"
27853
27854         # Fill OST0 (if it's not too large)
27855         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27856                    head -n1)
27857         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27858                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27859         fi
27860         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27861         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27862                 error "dd should fill OST0"
27863         stack_trap "rm -f $DIR/$tfile.1"
27864
27865         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27866         err=$?
27867         stack_trap "rm -f $DIR/$tfile.2"
27868
27869         # Check that short write completed as expected
27870         ls -la $DIR/$tfile.2
27871         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27872                 error "file is not 1M in size"
27873
27874         # dd above should not succeed, but don't error until here so we can
27875         # get debug info above
27876         [[ $err != 0 ]] ||
27877                 error "parallel dio write with enospc succeeded"
27878
27879         # Truncate source file to same length as output file and diff them
27880         $TRUNCATE $DIR/$tfile 1048576
27881         diff $DIR/$tfile $DIR/$tfile.2
27882         [[ $? == 0 ]] || error "data incorrect after short write"
27883 }
27884 run_test 398l "test enospc on intermediate stripe/RPC"
27885
27886 test_398m() { #  LU-13798
27887         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27888
27889         # Set up failure on OST0, the first stripe:
27890         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27891         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27892         # OST0 is on ost1, OST1 is on ost2.
27893         # So this fail_val specifies OST0
27894         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27895         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27896
27897         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27898                 error "parallel dio write with failure on first stripe succeeded"
27899         stack_trap "rm -f $DIR/$tfile"
27900         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27901
27902         # Place data in file for read
27903         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27904                 error "parallel dio write failed"
27905
27906         # Fail read on OST0, first stripe
27907         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27908         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27909         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27910                 error "parallel dio read with error on first stripe succeeded"
27911         rm -f $DIR/$tfile.2
27912         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27913
27914         # Switch to testing on OST1, second stripe
27915         # Clear file contents, maintain striping
27916         echo > $DIR/$tfile
27917         # Set up failure on OST1, second stripe:
27918         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27919         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27920
27921         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27922                 error "parallel dio write with failure on second stripe succeeded"
27923         stack_trap "rm -f $DIR/$tfile"
27924         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27925
27926         # Place data in file for read
27927         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27928                 error "parallel dio write failed"
27929
27930         # Fail read on OST1, second stripe
27931         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27932         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27933         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27934                 error "parallel dio read with error on second stripe succeeded"
27935         rm -f $DIR/$tfile.2
27936         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27937 }
27938 run_test 398m "test RPC failures with parallel dio"
27939
27940 # Parallel submission of DIO should not cause problems for append, but it's
27941 # important to verify.
27942 test_398n() { #  LU-13798
27943         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27944
27945         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27946                 error "dd to create source file failed"
27947         stack_trap "rm -f $DIR/$tfile"
27948
27949         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27950                 error "parallel dio write with failure on second stripe succeeded"
27951         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27952         diff $DIR/$tfile $DIR/$tfile.1
27953         [[ $? == 0 ]] || error "data incorrect after append"
27954
27955 }
27956 run_test 398n "test append with parallel DIO"
27957
27958 test_398o() {
27959         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27960 }
27961 run_test 398o "right kms with DIO"
27962
27963 test_398p()
27964 {
27965         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27966         which aiocp || skip_env "no aiocp installed"
27967
27968         local stripe_size=$((1024 * 1024)) #1 MiB
27969         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27970         local file_size=$((25 * stripe_size))
27971
27972         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27973         stack_trap "rm -f $DIR/$tfile*"
27974         # Just a bit bigger than the largest size in the test set below
27975         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27976                 error "buffered i/o to create file failed"
27977
27978         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27979                 $((stripe_size * 4)); do
27980
27981                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27982
27983                 echo "bs: $bs, file_size $file_size"
27984                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27985                         $DIR/$tfile.1 $DIR/$tfile.2 &
27986                 pid_dio1=$!
27987                 # Buffered I/O with similar but not the same block size
27988                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27989                         conv=notrunc &
27990                 pid_bio2=$!
27991                 wait $pid_dio1
27992                 rc1=$?
27993                 wait $pid_bio2
27994                 rc2=$?
27995                 if (( rc1 != 0 )); then
27996                         error "aio copy 1 w/bsize $bs failed: $rc1"
27997                 fi
27998                 if (( rc2 != 0 )); then
27999                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28000                 fi
28001
28002                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28003                         error "size incorrect"
28004                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
28005                         error "files differ, bsize $bs"
28006                 rm -f $DIR/$tfile.2
28007         done
28008 }
28009 run_test 398p "race aio with buffered i/o"
28010
28011 test_398q()
28012 {
28013         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28014
28015         local stripe_size=$((1024 * 1024)) #1 MiB
28016         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28017         local file_size=$((25 * stripe_size))
28018
28019         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28020         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28021
28022         # Just a bit bigger than the largest size in the test set below
28023         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28024                 error "buffered i/o to create file failed"
28025
28026         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28027                 $((stripe_size * 4)); do
28028
28029                 echo "bs: $bs, file_size $file_size"
28030                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
28031                         conv=notrunc oflag=direct iflag=direct &
28032                 pid_dio1=$!
28033                 # Buffered I/O with similar but not the same block size
28034                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28035                         conv=notrunc &
28036                 pid_bio2=$!
28037                 wait $pid_dio1
28038                 rc1=$?
28039                 wait $pid_bio2
28040                 rc2=$?
28041                 if (( rc1 != 0 )); then
28042                         error "dio copy 1 w/bsize $bs failed: $rc1"
28043                 fi
28044                 if (( rc2 != 0 )); then
28045                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28046                 fi
28047
28048                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28049                         error "size incorrect"
28050                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28051                         error "files differ, bsize $bs"
28052         done
28053
28054         rm -f $DIR/$tfile*
28055 }
28056 run_test 398q "race dio with buffered i/o"
28057
28058 test_398r() {
28059         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28060         echo "hello, world" > $DIR/$tfile
28061
28062         cancel_lru_locks osc
28063
28064 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28065         do_facet ost1 $LCTL set_param fail_loc=0x20f
28066         cat $DIR/$tfile > /dev/null && error "cat should fail"
28067         return 0
28068 }
28069 run_test 398r "i/o error on file read"
28070
28071 test_398s() {
28072         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28073                 skip "remote OST"
28074
28075         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28076                 error "mirror create failed"
28077
28078         echo "hello, world" > $DIR/$tfile
28079         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28080
28081         cancel_lru_locks osc
28082
28083 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28084         do_facet ost1 $LCTL set_param fail_loc=0x20f
28085         cat $DIR/$tfile > /dev/null && error "cat should fail"
28086         return 0
28087 }
28088 run_test 398s "i/o error on mirror file read"
28089
28090 test_fake_rw() {
28091         local read_write=$1
28092         if [ "$read_write" = "write" ]; then
28093                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28094         elif [ "$read_write" = "read" ]; then
28095                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28096         else
28097                 error "argument error"
28098         fi
28099
28100         # turn off debug for performance testing
28101         local saved_debug=$($LCTL get_param -n debug)
28102         $LCTL set_param debug=0
28103
28104         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28105
28106         # get ost1 size - $FSNAME-OST0000
28107         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28108         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28109         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28110
28111         if [ "$read_write" = "read" ]; then
28112                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28113         fi
28114
28115         local start_time=$(date +%s.%N)
28116         $dd_cmd bs=1M count=$blocks oflag=sync ||
28117                 error "real dd $read_write error"
28118         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28119
28120         if [ "$read_write" = "write" ]; then
28121                 rm -f $DIR/$tfile
28122         fi
28123
28124         # define OBD_FAIL_OST_FAKE_RW           0x238
28125         do_facet ost1 $LCTL set_param fail_loc=0x238
28126
28127         local start_time=$(date +%s.%N)
28128         $dd_cmd bs=1M count=$blocks oflag=sync ||
28129                 error "fake dd $read_write error"
28130         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28131
28132         if [ "$read_write" = "write" ]; then
28133                 # verify file size
28134                 cancel_lru_locks osc
28135                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28136                         error "$tfile size not $blocks MB"
28137         fi
28138         do_facet ost1 $LCTL set_param fail_loc=0
28139
28140         echo "fake $read_write $duration_fake vs. normal $read_write" \
28141                 "$duration in seconds"
28142         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28143                 error_not_in_vm "fake write is slower"
28144
28145         $LCTL set_param -n debug="$saved_debug"
28146         rm -f $DIR/$tfile
28147 }
28148 test_399a() { # LU-7655 for OST fake write
28149         remote_ost_nodsh && skip "remote OST with nodsh"
28150
28151         test_fake_rw write
28152 }
28153 run_test 399a "fake write should not be slower than normal write"
28154
28155 test_399b() { # LU-8726 for OST fake read
28156         remote_ost_nodsh && skip "remote OST with nodsh"
28157         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28158                 skip_env "ldiskfs only test"
28159         fi
28160
28161         test_fake_rw read
28162 }
28163 run_test 399b "fake read should not be slower than normal read"
28164
28165 test_400a() { # LU-1606, was conf-sanity test_74
28166         if ! which $CC > /dev/null 2>&1; then
28167                 skip_env "$CC is not installed"
28168         fi
28169
28170         local extra_flags=''
28171         local out=$TMP/$tfile
28172         local prefix=/usr/include/lustre
28173         local prog
28174
28175         # Oleg removes .c files in his test rig so test if any c files exist
28176         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28177                 skip_env "Needed .c test files are missing"
28178
28179         if ! [[ -d $prefix ]]; then
28180                 # Assume we're running in tree and fixup the include path.
28181                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28182                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28183                 extra_flags+=" -L$LUSTRE/utils/.libs"
28184         fi
28185
28186         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28187                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28188                         error "client api broken"
28189         done
28190         rm -f $out
28191 }
28192 run_test 400a "Lustre client api program can compile and link"
28193
28194 test_400b() { # LU-1606, LU-5011
28195         local header
28196         local out=$TMP/$tfile
28197         local prefix=/usr/include/linux/lustre
28198
28199         # We use a hard coded prefix so that this test will not fail
28200         # when run in tree. There are headers in lustre/include/lustre/
28201         # that are not packaged (like lustre_idl.h) and have more
28202         # complicated include dependencies (like config.h and lnet/types.h).
28203         # Since this test about correct packaging we just skip them when
28204         # they don't exist (see below) rather than try to fixup cppflags.
28205
28206         if ! which $CC > /dev/null 2>&1; then
28207                 skip_env "$CC is not installed"
28208         fi
28209
28210         for header in $prefix/*.h; do
28211                 if ! [[ -f "$header" ]]; then
28212                         continue
28213                 fi
28214
28215                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28216                         continue # lustre_ioctl.h is internal header
28217                 fi
28218
28219                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28220                         error "cannot compile '$header'"
28221         done
28222         rm -f $out
28223 }
28224 run_test 400b "packaged headers can be compiled"
28225
28226 test_401a() { #LU-7437
28227         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28228         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28229
28230         #count the number of parameters by "list_param -R"
28231         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28232         #count the number of parameters by listing proc files
28233         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28234         echo "proc_dirs='$proc_dirs'"
28235         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28236         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28237                       sort -u | wc -l)
28238
28239         [ $params -eq $procs ] ||
28240                 error "found $params parameters vs. $procs proc files"
28241
28242         # test the list_param -D option only returns directories
28243         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28244         #count the number of parameters by listing proc directories
28245         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28246                 sort -u | wc -l)
28247
28248         [ $params -eq $procs ] ||
28249                 error "found $params parameters vs. $procs proc files"
28250 }
28251 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28252
28253 test_401b() {
28254         # jobid_var may not allow arbitrary values, so use jobid_name
28255         # if available
28256         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28257                 local testname=jobid_name tmp='testing%p'
28258         else
28259                 local testname=jobid_var tmp=testing
28260         fi
28261
28262         local save=$($LCTL get_param -n $testname)
28263
28264         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28265                 error "no error returned when setting bad parameters"
28266
28267         local jobid_new=$($LCTL get_param -n foe $testname baz)
28268         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28269
28270         $LCTL set_param -n fog=bam $testname=$save bat=fog
28271         local jobid_old=$($LCTL get_param -n foe $testname bag)
28272         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28273 }
28274 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28275
28276 test_401c() {
28277         # jobid_var may not allow arbitrary values, so use jobid_name
28278         # if available
28279         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28280                 local testname=jobid_name
28281         else
28282                 local testname=jobid_var
28283         fi
28284
28285         local jobid_var_old=$($LCTL get_param -n $testname)
28286         local jobid_var_new
28287
28288         $LCTL set_param $testname= &&
28289                 error "no error returned for 'set_param a='"
28290
28291         jobid_var_new=$($LCTL get_param -n $testname)
28292         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28293                 error "$testname was changed by setting without value"
28294
28295         $LCTL set_param $testname &&
28296                 error "no error returned for 'set_param a'"
28297
28298         jobid_var_new=$($LCTL get_param -n $testname)
28299         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28300                 error "$testname was changed by setting without value"
28301 }
28302 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28303
28304 test_401d() {
28305         # jobid_var may not allow arbitrary values, so use jobid_name
28306         # if available
28307         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28308                 local testname=jobid_name new_value='foo=bar%p'
28309         else
28310                 local testname=jobid_var new_valuie=foo=bar
28311         fi
28312
28313         local jobid_var_old=$($LCTL get_param -n $testname)
28314         local jobid_var_new
28315
28316         $LCTL set_param $testname=$new_value ||
28317                 error "'set_param a=b' did not accept a value containing '='"
28318
28319         jobid_var_new=$($LCTL get_param -n $testname)
28320         [[ "$jobid_var_new" == "$new_value" ]] ||
28321                 error "'set_param a=b' failed on a value containing '='"
28322
28323         # Reset the $testname to test the other format
28324         $LCTL set_param $testname=$jobid_var_old
28325         jobid_var_new=$($LCTL get_param -n $testname)
28326         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28327                 error "failed to reset $testname"
28328
28329         $LCTL set_param $testname $new_value ||
28330                 error "'set_param a b' did not accept a value containing '='"
28331
28332         jobid_var_new=$($LCTL get_param -n $testname)
28333         [[ "$jobid_var_new" == "$new_value" ]] ||
28334                 error "'set_param a b' failed on a value containing '='"
28335
28336         $LCTL set_param $testname $jobid_var_old
28337         jobid_var_new=$($LCTL get_param -n $testname)
28338         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28339                 error "failed to reset $testname"
28340 }
28341 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28342
28343 test_401e() { # LU-14779
28344         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28345                 error "lctl list_param MGC* failed"
28346         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28347         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28348                 error "lctl get_param lru_size failed"
28349 }
28350 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28351
28352 test_402() {
28353         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28354         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28355                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28356         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28357                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28358                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28359         remote_mds_nodsh && skip "remote MDS with nodsh"
28360
28361         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28362 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28363         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28364         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28365                 echo "Touch failed - OK"
28366 }
28367 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28368
28369 test_403() {
28370         local file1=$DIR/$tfile.1
28371         local file2=$DIR/$tfile.2
28372         local tfile=$TMP/$tfile
28373
28374         rm -f $file1 $file2 $tfile
28375
28376         touch $file1
28377         ln $file1 $file2
28378
28379         # 30 sec OBD_TIMEOUT in ll_getattr()
28380         # right before populating st_nlink
28381         $LCTL set_param fail_loc=0x80001409
28382         stat -c %h $file1 > $tfile &
28383
28384         # create an alias, drop all locks and reclaim the dentry
28385         < $file2
28386         cancel_lru_locks mdc
28387         cancel_lru_locks osc
28388         sysctl -w vm.drop_caches=2
28389
28390         wait
28391
28392         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28393
28394         rm -f $tfile $file1 $file2
28395 }
28396 run_test 403 "i_nlink should not drop to zero due to aliasing"
28397
28398 test_404() { # LU-6601
28399         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28400                 skip "Need server version newer than 2.8.52"
28401         remote_mds_nodsh && skip "remote MDS with nodsh"
28402
28403         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28404                 awk '/osp .*-osc-MDT/ { print $4}')
28405
28406         local osp
28407         for osp in $mosps; do
28408                 echo "Deactivate: " $osp
28409                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28410                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28411                         awk -vp=$osp '$4 == p { print $2 }')
28412                 [ $stat = IN ] || {
28413                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28414                         error "deactivate error"
28415                 }
28416                 echo "Activate: " $osp
28417                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28418                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28419                         awk -vp=$osp '$4 == p { print $2 }')
28420                 [ $stat = UP ] || {
28421                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28422                         error "activate error"
28423                 }
28424         done
28425 }
28426 run_test 404 "validate manual {de}activated works properly for OSPs"
28427
28428 test_405() {
28429         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28430         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28431                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28432                         skip "Layout swap lock is not supported"
28433
28434         check_swap_layouts_support
28435         check_swap_layout_no_dom $DIR
28436
28437         test_mkdir $DIR/$tdir
28438         swap_lock_test -d $DIR/$tdir ||
28439                 error "One layout swap locked test failed"
28440 }
28441 run_test 405 "Various layout swap lock tests"
28442
28443 test_406() {
28444         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28445         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28446         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28448         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28449                 skip "Need MDS version at least 2.8.50"
28450
28451         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28452         local test_pool=$TESTNAME
28453
28454         pool_add $test_pool || error "pool_add failed"
28455         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28456                 error "pool_add_targets failed"
28457
28458         save_layout_restore_at_exit $MOUNT
28459
28460         # parent set default stripe count only, child will stripe from both
28461         # parent and fs default
28462         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28463                 error "setstripe $MOUNT failed"
28464         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28465         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28466         for i in $(seq 10); do
28467                 local f=$DIR/$tdir/$tfile.$i
28468                 touch $f || error "touch failed"
28469                 local count=$($LFS getstripe -c $f)
28470                 [ $count -eq $OSTCOUNT ] ||
28471                         error "$f stripe count $count != $OSTCOUNT"
28472                 local offset=$($LFS getstripe -i $f)
28473                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28474                 local size=$($LFS getstripe -S $f)
28475                 [ $size -eq $((def_stripe_size * 2)) ] ||
28476                         error "$f stripe size $size != $((def_stripe_size * 2))"
28477                 local pool=$($LFS getstripe -p $f)
28478                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28479         done
28480
28481         # change fs default striping, delete parent default striping, now child
28482         # will stripe from new fs default striping only
28483         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28484                 error "change $MOUNT default stripe failed"
28485         $LFS setstripe -c 0 $DIR/$tdir ||
28486                 error "delete $tdir default stripe failed"
28487         for i in $(seq 11 20); do
28488                 local f=$DIR/$tdir/$tfile.$i
28489                 touch $f || error "touch $f failed"
28490                 local count=$($LFS getstripe -c $f)
28491                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28492                 local offset=$($LFS getstripe -i $f)
28493                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28494                 local size=$($LFS getstripe -S $f)
28495                 [ $size -eq $def_stripe_size ] ||
28496                         error "$f stripe size $size != $def_stripe_size"
28497                 local pool=$($LFS getstripe -p $f)
28498                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28499         done
28500
28501         unlinkmany $DIR/$tdir/$tfile. 1 20
28502
28503         local f=$DIR/$tdir/$tfile
28504         pool_remove_all_targets $test_pool $f
28505         pool_remove $test_pool $f
28506 }
28507 run_test 406 "DNE support fs default striping"
28508
28509 test_407() {
28510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28511         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28512                 skip "Need MDS version at least 2.8.55"
28513         remote_mds_nodsh && skip "remote MDS with nodsh"
28514
28515         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28516                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28517         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28518                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28519         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28520
28521         #define OBD_FAIL_DT_TXN_STOP    0x2019
28522         for idx in $(seq $MDSCOUNT); do
28523                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28524         done
28525         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28526         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28527                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28528         true
28529 }
28530 run_test 407 "transaction fail should cause operation fail"
28531
28532 test_408() {
28533         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28534
28535         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28536         lctl set_param fail_loc=0x8000040a
28537         # let ll_prepare_partial_page() fail
28538         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28539
28540         rm -f $DIR/$tfile
28541
28542         # create at least 100 unused inodes so that
28543         # shrink_icache_memory(0) should not return 0
28544         touch $DIR/$tfile-{0..100}
28545         rm -f $DIR/$tfile-{0..100}
28546         sync
28547
28548         echo 2 > /proc/sys/vm/drop_caches
28549 }
28550 run_test 408 "drop_caches should not hang due to page leaks"
28551
28552 test_409()
28553 {
28554         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28555
28556         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28557         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28558         touch $DIR/$tdir/guard || error "(2) Fail to create"
28559
28560         local PREFIX=$(str_repeat 'A' 128)
28561         echo "Create 1K hard links start at $(date)"
28562         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28563                 error "(3) Fail to hard link"
28564
28565         echo "Links count should be right although linkEA overflow"
28566         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28567         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28568         [ $linkcount -eq 1001 ] ||
28569                 error "(5) Unexpected hard links count: $linkcount"
28570
28571         echo "List all links start at $(date)"
28572         ls -l $DIR/$tdir/foo > /dev/null ||
28573                 error "(6) Fail to list $DIR/$tdir/foo"
28574
28575         echo "Unlink hard links start at $(date)"
28576         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28577                 error "(7) Fail to unlink"
28578         echo "Unlink hard links finished at $(date)"
28579 }
28580 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28581
28582 test_410()
28583 {
28584         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28585                 skip "Need client version at least 2.9.59"
28586
28587         # Create a file, and stat it from the kernel
28588         local testfile=$DIR/$tfile
28589         touch $testfile
28590
28591         local run_id=$RANDOM
28592         local my_ino=$(stat --format "%i" $testfile)
28593
28594         # Try to insert the module.
28595         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28596                 error "load_module failed"
28597
28598         # Anything but success is a test failure
28599         dmesg | grep -q \
28600             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28601             error "no inode match"
28602
28603         # Remove the test module
28604         rmmod -v kinode ||
28605                 error "rmmod failed (may trigger a failure in a later test)"
28606 }
28607 run_test 410 "Test inode number returned from kernel thread"
28608
28609 cleanup_test411_cgroup() {
28610         trap 0
28611         cat $1/memory.stat
28612         rmdir "$1"
28613 }
28614
28615 test_411a() {
28616         local cg_basedir=/sys/fs/cgroup/memory
28617         # LU-9966
28618         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28619                 skip "no setup for cgroup"
28620
28621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28622                 error "test file creation failed"
28623         cancel_lru_locks osc
28624
28625         # Create a very small memory cgroup to force a slab allocation error
28626         local cgdir=$cg_basedir/osc_slab_alloc
28627         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28628         trap "cleanup_test411_cgroup $cgdir" EXIT
28629         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28630         echo 1M > $cgdir/memory.limit_in_bytes
28631
28632         # Should not LBUG, just be killed by oom-killer
28633         # dd will return 0 even allocation failure in some environment.
28634         # So don't check return value
28635         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28636         cleanup_test411_cgroup $cgdir
28637
28638         return 0
28639 }
28640 run_test 411a "Slab allocation error with cgroup does not LBUG"
28641
28642 test_411b() {
28643         local cg_basedir=/sys/fs/cgroup/memory
28644         # LU-9966
28645         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28646                 skip "no setup for cgroup"
28647         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28648         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28649         # limit, so we have 384M in cgroup
28650         # (arm) this seems to hit OOM more often than x86, so 1024M
28651         if [[ $(uname -m) = aarch64 ]]; then
28652                 local memlimit_mb=1024
28653         else
28654                 local memlimit_mb=384
28655         fi
28656
28657         # Create a cgroup and set memory limit
28658         # (tfile is used as an easy way to get a recognizable cgroup name)
28659         local cgdir=$cg_basedir/$tfile
28660         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28661         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28662         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28663
28664         echo "writing first file"
28665         # Write a file 4x the memory limit in size
28666         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28667                 error "(1) failed to write successfully"
28668
28669         sync
28670         cancel_lru_locks osc
28671
28672         rm -f $DIR/$tfile
28673         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28674
28675         # Try writing at a larger block size
28676         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28677         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28678         # need *some* memory to do IO in)
28679         echo "writing at larger block size"
28680         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28681                 error "(3) failed to write successfully"
28682
28683         sync
28684         cancel_lru_locks osc
28685         rm -f $DIR/$tfile
28686         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28687
28688         # Try writing multiple files at once
28689         echo "writing multiple files"
28690         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28691         local pid1=$!
28692         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28693         local pid2=$!
28694         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28695         local pid3=$!
28696         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28697         local pid4=$!
28698
28699         wait $pid1
28700         local rc1=$?
28701         wait $pid2
28702         local rc2=$?
28703         wait $pid3
28704         local rc3=$?
28705         wait $pid4
28706         local rc4=$?
28707         if (( rc1 != 0)); then
28708                 error "error $rc1 writing to file from $pid1"
28709         fi
28710         if (( rc2 != 0)); then
28711                 error "error $rc2 writing to file from $pid2"
28712         fi
28713         if (( rc3 != 0)); then
28714                 error "error $rc3 writing to file from $pid3"
28715         fi
28716         if (( rc4 != 0)); then
28717                 error "error $rc4 writing to file from $pid4"
28718         fi
28719
28720         sync
28721         cancel_lru_locks osc
28722
28723         # These files can be large-ish (~1 GiB total), so delete them rather
28724         # than leave for later cleanup
28725         rm -f $DIR/$tfile.*
28726         return 0
28727 }
28728 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28729
28730 test_412() {
28731         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28732         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28733                 skip "Need server version at least 2.10.55"
28734
28735         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28736                 error "mkdir failed"
28737         $LFS getdirstripe $DIR/$tdir
28738         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28739         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28740                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28741         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28742         [ $stripe_count -eq 2 ] ||
28743                 error "expect 2 get $stripe_count"
28744
28745         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28746
28747         local index
28748         local index2
28749
28750         # subdirs should be on the same MDT as parent
28751         for i in $(seq 0 $((MDSCOUNT - 1))); do
28752                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28753                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28754                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28755                 (( index == i )) || error "mdt$i/sub on MDT$index"
28756         done
28757
28758         # stripe offset -1, ditto
28759         for i in {1..10}; do
28760                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28761                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28762                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28763                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28764                 (( index == index2 )) ||
28765                         error "qos$i on MDT$index, sub on MDT$index2"
28766         done
28767
28768         local testdir=$DIR/$tdir/inherit
28769
28770         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28771         # inherit 2 levels
28772         for i in 1 2; do
28773                 testdir=$testdir/s$i
28774                 mkdir $testdir || error "mkdir $testdir failed"
28775                 index=$($LFS getstripe -m $testdir)
28776                 (( index == 1 )) ||
28777                         error "$testdir on MDT$index"
28778         done
28779
28780         # not inherit any more
28781         testdir=$testdir/s3
28782         mkdir $testdir || error "mkdir $testdir failed"
28783         getfattr -d -m dmv $testdir | grep dmv &&
28784                 error "default LMV set on $testdir" || true
28785 }
28786 run_test 412 "mkdir on specific MDTs"
28787
28788 TEST413_COUNT=${TEST413_COUNT:-200}
28789
28790 #
28791 # set_maxage() is used by test_413 only.
28792 # This is a helper function to set maxage. Does not return any value.
28793 # Input: maxage to set
28794 #
28795 set_maxage() {
28796         local lmv_qos_maxage
28797         local lod_qos_maxage
28798         local new_maxage=$1
28799
28800         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28801         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28802         stack_trap "$LCTL set_param \
28803                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28804         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28805                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28806         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28807                 lod.*.mdt_qos_maxage=$new_maxage
28808         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28809                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28810 }
28811
28812 generate_uneven_mdts() {
28813         local threshold=$1
28814         local ffree
28815         local bavail
28816         local max
28817         local min
28818         local max_index
28819         local min_index
28820         local tmp
28821         local i
28822
28823         echo
28824         echo "Check for uneven MDTs: "
28825
28826         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28827         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28828         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28829
28830         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28831         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28832         max_index=0
28833         min_index=0
28834         for ((i = 1; i < ${#ffree[@]}; i++)); do
28835                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28836                 if [ $tmp -gt $max ]; then
28837                         max=$tmp
28838                         max_index=$i
28839                 fi
28840                 if [ $tmp -lt $min ]; then
28841                         min=$tmp
28842                         min_index=$i
28843                 fi
28844         done
28845
28846         (( min > 0 )) || skip "low space on MDT$min_index"
28847         (( ${ffree[min_index]} > 0 )) ||
28848                 skip "no free files on MDT$min_index"
28849         (( ${ffree[min_index]} < 10000000 )) ||
28850                 skip "too many free files on MDT$min_index"
28851
28852         # Check if we need to generate uneven MDTs
28853         local diff=$(((max - min) * 100 / min))
28854         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28855         local testdir # individual folder within $testdirp
28856         local start
28857         local cmd
28858
28859         # fallocate is faster to consume space on MDT, if available
28860         if check_fallocate_supported mds$((min_index + 1)); then
28861                 cmd="fallocate -l 128K "
28862         else
28863                 cmd="dd if=/dev/zero bs=128K count=1 of="
28864         fi
28865
28866         echo "using cmd $cmd"
28867         for (( i = 0; diff < threshold; i++ )); do
28868                 testdir=${testdirp}/$i
28869                 [ -d $testdir ] && continue
28870
28871                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28872
28873                 mkdir -p $testdirp
28874                 # generate uneven MDTs, create till $threshold% diff
28875                 echo -n "weight diff=$diff% must be > $threshold% ..."
28876                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28877                 $LFS mkdir -i $min_index $testdir ||
28878                         error "mkdir $testdir failed"
28879                 $LFS setstripe -E 1M -L mdt $testdir ||
28880                         error "setstripe $testdir failed"
28881                 start=$SECONDS
28882                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28883                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28884                 done
28885                 sync; sleep 1; sync
28886
28887                 # wait for QOS to update
28888                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28889
28890                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28891                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28892                 max=$(((${ffree[max_index]} >> 8) *
28893                         (${bavail[max_index]} * bsize >> 16)))
28894                 min=$(((${ffree[min_index]} >> 8) *
28895                         (${bavail[min_index]} * bsize >> 16)))
28896                 (( min > 0 )) || skip "low space on MDT$min_index"
28897                 diff=$(((max - min) * 100 / min))
28898         done
28899
28900         echo "MDT filesfree available: ${ffree[*]}"
28901         echo "MDT blocks available: ${bavail[*]}"
28902         echo "weight diff=$diff%"
28903 }
28904
28905 test_qos_mkdir() {
28906         local mkdir_cmd=$1
28907         local stripe_count=$2
28908         local mdts=$(comma_list $(mdts_nodes))
28909
28910         local testdir
28911         local lmv_qos_prio_free
28912         local lmv_qos_threshold_rr
28913         local lod_qos_prio_free
28914         local lod_qos_threshold_rr
28915         local total
28916         local count
28917         local i
28918
28919         # @total is total directories created if it's testing plain
28920         # directories, otherwise it's total stripe object count for
28921         # striped directories test.
28922         # remote/striped directory unlinking is slow on zfs and may
28923         # timeout, test with fewer directories
28924         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28925
28926         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28927         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28928         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28929                 head -n1)
28930         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28931         stack_trap "$LCTL set_param \
28932                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28933         stack_trap "$LCTL set_param \
28934                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28935
28936         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28937                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28938         lod_qos_prio_free=${lod_qos_prio_free%%%}
28939         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28940                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28941         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28942         stack_trap "do_nodes $mdts $LCTL set_param \
28943                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28944         stack_trap "do_nodes $mdts $LCTL set_param \
28945                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28946
28947         # decrease statfs age, so that it can be updated in time
28948         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28949         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28950
28951         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28952         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28953
28954         testdir=$DIR/$tdir-s$stripe_count/rr
28955
28956         local stripe_index=$($LFS getstripe -m $testdir)
28957         local test_mkdir_rr=true
28958
28959         getfattr -d -m dmv -e hex $testdir | grep dmv
28960         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28961                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28962                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28963                         test_mkdir_rr=false
28964         fi
28965
28966         echo
28967         $test_mkdir_rr &&
28968                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28969                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28970
28971         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28972         for (( i = 0; i < total / stripe_count; i++ )); do
28973                 eval $mkdir_cmd $testdir/subdir$i ||
28974                         error "$mkdir_cmd subdir$i failed"
28975         done
28976
28977         for (( i = 0; i < $MDSCOUNT; i++ )); do
28978                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28979                 echo "$count directories created on MDT$i"
28980                 if $test_mkdir_rr; then
28981                         (( count == total / stripe_count / MDSCOUNT )) ||
28982                                 error "subdirs are not evenly distributed"
28983                 elif (( i == stripe_index )); then
28984                         (( count == total / stripe_count )) ||
28985                                 error "$count subdirs created on MDT$i"
28986                 else
28987                         (( count == 0 )) ||
28988                                 error "$count subdirs created on MDT$i"
28989                 fi
28990
28991                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28992                         count=$($LFS getdirstripe $testdir/* |
28993                                 grep -c -P "^\s+$i\t")
28994                         echo "$count stripes created on MDT$i"
28995                         # deviation should < 5% of average
28996                         delta=$((count - total / MDSCOUNT))
28997                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28998                                 error "stripes are not evenly distributed"
28999                 fi
29000         done
29001
29002         echo
29003         echo "Check for uneven MDTs: "
29004
29005         local ffree
29006         local bavail
29007         local max
29008         local min
29009         local max_index
29010         local min_index
29011         local tmp
29012
29013         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29014         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29015         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29016
29017         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29018         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29019         max_index=0
29020         min_index=0
29021         for ((i = 1; i < ${#ffree[@]}; i++)); do
29022                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29023                 if [ $tmp -gt $max ]; then
29024                         max=$tmp
29025                         max_index=$i
29026                 fi
29027                 if [ $tmp -lt $min ]; then
29028                         min=$tmp
29029                         min_index=$i
29030                 fi
29031         done
29032         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29033
29034         (( min > 0 )) || skip "low space on MDT$min_index"
29035         (( ${ffree[min_index]} < 10000000 )) ||
29036                 skip "too many free files on MDT$min_index"
29037
29038         generate_uneven_mdts 120
29039
29040         echo "MDT filesfree available: ${ffree[*]}"
29041         echo "MDT blocks available: ${bavail[*]}"
29042         echo "weight diff=$(((max - min) * 100 / min))%"
29043         echo
29044         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29045
29046         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29047         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29048         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29049         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29050
29051         sleep 1
29052
29053         testdir=$DIR/$tdir-s$stripe_count/qos
29054
29055         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29056         for (( i = 0; i < total / stripe_count; i++ )); do
29057                 eval $mkdir_cmd $testdir/subdir$i ||
29058                         error "$mkdir_cmd subdir$i failed"
29059         done
29060
29061         max=0
29062         for (( i = 0; i < $MDSCOUNT; i++ )); do
29063                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29064                 (( count > max )) && max=$count
29065                 echo "$count directories created on MDT$i : curmax=$max"
29066         done
29067
29068         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29069
29070         # D-value should > 10% of average
29071         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29072                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29073
29074         # ditto for stripes
29075         if (( stripe_count > 1 )); then
29076                 max=0
29077                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29078                         count=$($LFS getdirstripe $testdir/* |
29079                                 grep -c -P "^\s+$i\t")
29080                         (( count > max )) && max=$count
29081                         echo "$count stripes created on MDT$i"
29082                 done
29083
29084                 min=$($LFS getdirstripe $testdir/* |
29085                         grep -c -P "^\s+$min_index\t")
29086                 (( max - min > total / MDSCOUNT / 10 )) ||
29087                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29088         fi
29089 }
29090
29091 most_full_mdt() {
29092         local ffree
29093         local bavail
29094         local bsize
29095         local min
29096         local min_index
29097         local tmp
29098
29099         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29100         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29101         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29102
29103         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29104         min_index=0
29105         for ((i = 1; i < ${#ffree[@]}; i++)); do
29106                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29107                 (( tmp < min )) && min=$tmp && min_index=$i
29108         done
29109
29110         echo -n $min_index
29111 }
29112
29113 test_413a() {
29114         [ $MDSCOUNT -lt 2 ] &&
29115                 skip "We need at least 2 MDTs for this test"
29116
29117         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29118                 skip "Need server version at least 2.12.52"
29119
29120         local stripe_max=$((MDSCOUNT - 1))
29121         local stripe_count
29122
29123         # let caller set maxage for latest result
29124         set_maxage 1
29125
29126         # fill MDT unevenly
29127         generate_uneven_mdts 120
29128
29129         # test 4-stripe directory at most, otherwise it's too slow
29130         # We are being very defensive. Although Autotest uses 4 MDTs.
29131         # We make sure stripe_max does not go over 4.
29132         (( stripe_max > 4 )) && stripe_max=4
29133         # unlinking striped directory is slow on zfs, and may timeout, only test
29134         # plain directory
29135         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29136         for stripe_count in $(seq 1 $stripe_max); do
29137                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29138                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29139                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29140                         error "mkdir failed"
29141                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29142         done
29143 }
29144 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29145
29146 test_413b() {
29147         [ $MDSCOUNT -lt 2 ] &&
29148                 skip "We need at least 2 MDTs for this test"
29149
29150         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29151                 skip "Need server version at least 2.12.52"
29152
29153         local stripe_max=$((MDSCOUNT - 1))
29154         local testdir
29155         local stripe_count
29156
29157         # let caller set maxage for latest result
29158         set_maxage 1
29159
29160         # fill MDT unevenly
29161         generate_uneven_mdts 120
29162
29163         # test 4-stripe directory at most, otherwise it's too slow
29164         # We are being very defensive. Although Autotest uses 4 MDTs.
29165         # We make sure stripe_max does not go over 4.
29166         (( stripe_max > 4 )) && stripe_max=4
29167         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29168         for stripe_count in $(seq 1 $stripe_max); do
29169                 testdir=$DIR/$tdir-s$stripe_count
29170                 mkdir $testdir || error "mkdir $testdir failed"
29171                 mkdir $testdir/rr || error "mkdir rr failed"
29172                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29173                         error "mkdir qos failed"
29174                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29175                         $testdir/rr || error "setdirstripe rr failed"
29176                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29177                         error "setdirstripe failed"
29178                 test_qos_mkdir "mkdir" $stripe_count
29179         done
29180 }
29181 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29182
29183 test_413c() {
29184         (( $MDSCOUNT >= 2 )) ||
29185                 skip "We need at least 2 MDTs for this test"
29186
29187         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29188                 skip "Need server version at least 2.14.51"
29189
29190         local testdir
29191         local inherit
29192         local inherit_rr
29193         local lmv_qos_maxage
29194         local lod_qos_maxage
29195
29196         # let caller set maxage for latest result
29197         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29198         $LCTL set_param lmv.*.qos_maxage=1
29199         stack_trap "$LCTL set_param \
29200                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29201         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29202                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29203         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29204                 lod.*.mdt_qos_maxage=1
29205         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29206                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29207
29208         # fill MDT unevenly
29209         generate_uneven_mdts 120
29210
29211         testdir=$DIR/${tdir}-s1
29212         mkdir $testdir || error "mkdir $testdir failed"
29213         mkdir $testdir/rr || error "mkdir rr failed"
29214         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29215         # default max_inherit is -1, default max_inherit_rr is 0
29216         $LFS setdirstripe -D -c 1 $testdir/rr ||
29217                 error "setdirstripe rr failed"
29218         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29219                 error "setdirstripe qos failed"
29220         test_qos_mkdir "mkdir" 1
29221
29222         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29223         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29224         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29225         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29226         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29227
29228         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29229         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29230         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29231         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29232         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29233         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29234         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29235                 error "level2 shouldn't have default LMV" || true
29236 }
29237 run_test 413c "mkdir with default LMV max inherit rr"
29238
29239 test_413d() {
29240         (( MDSCOUNT >= 2 )) ||
29241                 skip "We need at least 2 MDTs for this test"
29242
29243         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29244                 skip "Need server version at least 2.14.51"
29245
29246         local lmv_qos_threshold_rr
29247
29248         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29249                 head -n1)
29250         stack_trap "$LCTL set_param \
29251                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29252
29253         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29254         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29255         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29256                 error "$tdir shouldn't have default LMV"
29257         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29258                 error "mkdir sub failed"
29259
29260         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29261
29262         (( count == 100 )) || error "$count subdirs on MDT0"
29263 }
29264 run_test 413d "inherit ROOT default LMV"
29265
29266 test_413e() {
29267         (( MDSCOUNT >= 2 )) ||
29268                 skip "We need at least 2 MDTs for this test"
29269         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29270                 skip "Need server version at least 2.14.55"
29271
29272         local testdir=$DIR/$tdir
29273         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29274         local max_inherit
29275         local sub_max_inherit
29276
29277         mkdir -p $testdir || error "failed to create $testdir"
29278
29279         # set default max-inherit to -1 if stripe count is 0 or 1
29280         $LFS setdirstripe -D -c 1 $testdir ||
29281                 error "failed to set default LMV"
29282         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29283         (( max_inherit == -1 )) ||
29284                 error "wrong max_inherit value $max_inherit"
29285
29286         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29287         $LFS setdirstripe -D -c -1 $testdir ||
29288                 error "failed to set default LMV"
29289         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29290         (( max_inherit > 0 )) ||
29291                 error "wrong max_inherit value $max_inherit"
29292
29293         # and the subdir will decrease the max_inherit by 1
29294         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29295         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29296         (( sub_max_inherit == max_inherit - 1)) ||
29297                 error "wrong max-inherit of subdir $sub_max_inherit"
29298
29299         # check specified --max-inherit and warning message
29300         stack_trap "rm -f $tmpfile"
29301         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29302                 error "failed to set default LMV"
29303         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29304         (( max_inherit == -1 )) ||
29305                 error "wrong max_inherit value $max_inherit"
29306
29307         # check the warning messages
29308         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29309                 error "failed to detect warning string"
29310         fi
29311 }
29312 run_test 413e "check default max-inherit value"
29313
29314 test_fs_dmv_inherit()
29315 {
29316         local testdir=$DIR/$tdir
29317
29318         local count
29319         local inherit
29320         local inherit_rr
29321
29322         for i in 1 2; do
29323                 mkdir $testdir || error "mkdir $testdir failed"
29324                 count=$($LFS getdirstripe -D -c $testdir)
29325                 (( count == 1 )) ||
29326                         error "$testdir default LMV count mismatch $count != 1"
29327                 inherit=$($LFS getdirstripe -D -X $testdir)
29328                 (( inherit == 3 - i )) ||
29329                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29330                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29331                 (( inherit_rr == 3 - i )) ||
29332                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29333                 testdir=$testdir/sub
29334         done
29335
29336         mkdir $testdir || error "mkdir $testdir failed"
29337         count=$($LFS getdirstripe -D -c $testdir)
29338         (( count == 0 )) ||
29339                 error "$testdir default LMV count not zero: $count"
29340 }
29341
29342 test_413f() {
29343         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29344
29345         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29346                 skip "Need server version at least 2.14.55"
29347
29348         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29349                 error "dump $DIR default LMV failed"
29350         stack_trap "setfattr --restore=$TMP/dmv.ea"
29351
29352         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29353                 error "set $DIR default LMV failed"
29354
29355         test_fs_dmv_inherit
29356 }
29357 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29358
29359 test_413g() {
29360         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29361
29362         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29363         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29364                 error "dump $DIR default LMV failed"
29365         stack_trap "setfattr --restore=$TMP/dmv.ea"
29366
29367         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29368                 error "set $DIR default LMV failed"
29369
29370         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29371                 error "mount $MOUNT2 failed"
29372         stack_trap "umount_client $MOUNT2"
29373
29374         local saved_DIR=$DIR
29375
29376         export DIR=$MOUNT2
29377
29378         stack_trap "export DIR=$saved_DIR"
29379
29380         # first check filesystem-wide default LMV inheritance
29381         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29382
29383         # then check subdirs are spread to all MDTs
29384         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29385
29386         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29387
29388         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29389 }
29390 run_test 413g "enforce ROOT default LMV on subdir mount"
29391
29392 test_413h() {
29393         (( MDSCOUNT >= 2 )) ||
29394                 skip "We need at least 2 MDTs for this test"
29395
29396         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29397                 skip "Need server version at least 2.15.50.6"
29398
29399         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29400
29401         stack_trap "$LCTL set_param \
29402                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29403         $LCTL set_param lmv.*.qos_maxage=1
29404
29405         local depth=5
29406         local rr_depth=4
29407         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29408         local count=$((MDSCOUNT * 20))
29409
29410         generate_uneven_mdts 50
29411
29412         mkdir -p $dir || error "mkdir $dir failed"
29413         stack_trap "rm -rf $dir"
29414         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29415                 --max-inherit-rr=$rr_depth $dir
29416
29417         for ((d=0; d < depth + 2; d++)); do
29418                 log "dir=$dir:"
29419                 for ((sub=0; sub < count; sub++)); do
29420                         mkdir $dir/d$sub
29421                 done
29422                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29423                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29424                 # subdirs within $rr_depth should be created round-robin
29425                 if (( d < rr_depth )); then
29426                         (( ${num[0]} != count )) ||
29427                                 error "all objects created on MDT ${num[1]}"
29428                 fi
29429
29430                 dir=$dir/d0
29431         done
29432 }
29433 run_test 413h "don't stick to parent for round-robin dirs"
29434
29435 test_413i() {
29436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29437
29438         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29439                 skip "Need server version at least 2.14.55"
29440
29441         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29442                 error "dump $DIR default LMV failed"
29443         stack_trap "setfattr --restore=$TMP/dmv.ea"
29444
29445         local testdir=$DIR/$tdir
29446         local def_max_rr=1
29447         local def_max=3
29448         local count
29449
29450         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29451                 --max-inherit-rr=$def_max_rr $DIR ||
29452                 error "set $DIR default LMV failed"
29453
29454         for i in $(seq 2 3); do
29455                 def_max=$((def_max - 1))
29456                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29457
29458                 mkdir $testdir
29459                 # RR is decremented and keeps zeroed once exhausted
29460                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29461                 (( count == def_max_rr )) ||
29462                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29463
29464                 # max-inherit is decremented
29465                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29466                 (( count == def_max )) ||
29467                         error_noexit "$testdir: max-inherit $count != $def_max"
29468
29469                 testdir=$testdir/d$i
29470         done
29471
29472         # d3 is the last inherited from ROOT, no inheritance anymore
29473         # i.e. no the default layout anymore
29474         mkdir -p $testdir/d4/d5
29475         count=$($LFS getdirstripe -D --max-inherit $testdir)
29476         (( count == -1 )) ||
29477                 error_noexit "$testdir: max-inherit $count != -1"
29478
29479         local p_count=$($LFS getdirstripe -i $testdir)
29480
29481         for i in $(seq 4 5); do
29482                 testdir=$testdir/d$i
29483
29484                 # the root default layout is not applied once exhausted
29485                 count=$($LFS getdirstripe -i $testdir)
29486                 (( count == p_count )) ||
29487                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29488         done
29489
29490         $LFS setdirstripe -i 0 $DIR/d2
29491         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29492         (( count == -1 )) ||
29493                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29494 }
29495 run_test 413i "check default layout inheritance"
29496
29497 test_413j()
29498 {
29499         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29500
29501         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29502         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29503                 error "setdirstripe $tdir failed"
29504
29505         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29506                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29507
29508         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29509         # setfattr dmv calls setdirstripe -D
29510         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29511                 error "setfattr sub failed"
29512         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29513                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29514
29515         [ $value == $value2 ] || error "dmv mismatch"
29516
29517         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29518
29519         # do not allow remove dmv by setfattr -x
29520         do_nodes $(comma_list $(mdts_nodes)) \
29521                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29522         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29523         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29524
29525         # allow remove dmv by setfattr -x
29526         do_nodes $(comma_list $(mdts_nodes)) \
29527                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29528         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29529         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29530         do_nodes $(comma_list $(mdts_nodes)) \
29531                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29532 }
29533 run_test 413j "set default LMV by setxattr"
29534
29535 test_413k() {
29536         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29537                 skip "Need server version at least 2.15.60"
29538
29539         local index1
29540         local index2
29541         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29542         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29543         local prefixes="abc:123:foo bar"
29544
29545         # add prefixes
29546         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29547         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29548
29549         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29550         index1=$($LFS getstripe -m $DIR/$tdir)
29551         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29552                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29553                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29554                 ((index1 == index2)) ||
29555                         error "$tdir on MDT$index1, $dname on MDT$index2"
29556         done
29557
29558         # remove prefixes
29559         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29560
29561         # total prefixes length > PAGE_SIZE can be printed correctly
29562         for c in {a..z}; do
29563                 prefixes=$(str_repeat $c 255)
29564                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29565         done
29566         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29567         ((count2 == count + 26)) ||
29568                 error "prefixes count $count2 != $((count + 26))"
29569 }
29570 run_test 413k "QoS mkdir exclude prefixes"
29571
29572 test_413z() {
29573         local pids=""
29574         local subdir
29575         local pid
29576
29577         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29578                 unlinkmany $subdir/f. $TEST413_COUNT &
29579                 pids="$pids $!"
29580         done
29581
29582         for pid in $pids; do
29583                 wait $pid
29584         done
29585
29586         true
29587 }
29588 run_test 413z "413 test cleanup"
29589
29590 test_414() {
29591 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29592         $LCTL set_param fail_loc=0x80000521
29593         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29594         rm -f $DIR/$tfile
29595         # This error path has sometimes left inflight requests dangling, so
29596         # test for this by remounting the client (umount will hang if there's
29597         # a dangling request)
29598         umount_client $MOUNT
29599         mount_client $MOUNT
29600 }
29601 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29602
29603 test_415() {
29604         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29605         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29606                 skip "Need server version at least 2.11.52"
29607
29608         # LU-11102
29609         local total=500
29610         local max=120
29611
29612         # this test may be slow on ZFS
29613         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29614
29615         # though this test is designed for striped directory, let's test normal
29616         # directory too since lock is always saved as CoS lock.
29617         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29618         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29619         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29620         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29621         wait_delete_completed_mds
29622
29623         # run a loop without concurrent touch to measure rename duration.
29624         # only for test debug/robustness, NOT part of COS functional test.
29625         local start_time=$SECONDS
29626         for ((i = 0; i < total; i++)); do
29627                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29628                         > /dev/null
29629         done
29630         local baseline=$((SECONDS - start_time))
29631         echo "rename $total files without 'touch' took $baseline sec"
29632
29633         (
29634                 while true; do
29635                         touch $DIR/$tdir
29636                 done
29637         ) &
29638         local setattr_pid=$!
29639
29640         # rename files back to original name so unlinkmany works
29641         start_time=$SECONDS
29642         for ((i = 0; i < total; i++)); do
29643                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29644                         > /dev/null
29645         done
29646         local duration=$((SECONDS - start_time))
29647
29648         kill -9 $setattr_pid
29649
29650         echo "rename $total files with 'touch' took $duration sec"
29651         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29652         (( duration <= max )) ||
29653                 error_not_in_vm "rename took $duration > $max sec"
29654 }
29655 run_test 415 "lock revoke is not missing"
29656
29657 test_416() {
29658         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29659                 skip "Need server version at least 2.11.55"
29660
29661         # define OBD_FAIL_OSD_TXN_START    0x19a
29662         do_facet mds1 lctl set_param fail_loc=0x19a
29663
29664         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29665
29666         true
29667 }
29668 run_test 416 "transaction start failure won't cause system hung"
29669
29670 cleanup_417() {
29671         trap 0
29672         do_nodes $(comma_list $(mdts_nodes)) \
29673                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29674         do_nodes $(comma_list $(mdts_nodes)) \
29675                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29676         do_nodes $(comma_list $(mdts_nodes)) \
29677                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29678 }
29679
29680 test_417() {
29681         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29682         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29683                 skip "Need MDS version at least 2.11.56"
29684
29685         trap cleanup_417 RETURN EXIT
29686
29687         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29688         do_nodes $(comma_list $(mdts_nodes)) \
29689                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29690         $LFS migrate -m 0 $DIR/$tdir.1 &&
29691                 error "migrate dir $tdir.1 should fail"
29692
29693         do_nodes $(comma_list $(mdts_nodes)) \
29694                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29695         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29696                 error "create remote dir $tdir.2 should fail"
29697
29698         do_nodes $(comma_list $(mdts_nodes)) \
29699                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29700         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29701                 error "create striped dir $tdir.3 should fail"
29702         true
29703 }
29704 run_test 417 "disable remote dir, striped dir and dir migration"
29705
29706 # Checks that the outputs of df [-i] and lfs df [-i] match
29707 #
29708 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29709 check_lfs_df() {
29710         local dir=$2
29711         local inodes
29712         local df_out
29713         local lfs_df_out
29714         local count
29715         local passed=false
29716
29717         # blocks or inodes
29718         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29719
29720         for count in {1..100}; do
29721                 do_nodes "$CLIENTS" \
29722                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29723                 sync; sleep 0.2
29724
29725                 # read the lines of interest
29726                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29727                         error "df $inodes $dir | tail -n +2 failed"
29728                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29729                         error "lfs df $inodes $dir | grep summary: failed"
29730
29731                 # skip first substrings of each output as they are different
29732                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29733                 # compare the two outputs
29734                 passed=true
29735                 #  skip "available" on MDT until LU-13997 is fixed.
29736                 #for i in {1..5}; do
29737                 for i in 1 2 4 5; do
29738                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29739                 done
29740                 $passed && break
29741         done
29742
29743         if ! $passed; then
29744                 df -P $inodes $dir
29745                 echo
29746                 lfs df $inodes $dir
29747                 error "df and lfs df $1 output mismatch: "      \
29748                       "df ${inodes}: ${df_out[*]}, "            \
29749                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29750         fi
29751 }
29752
29753 test_418() {
29754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29755
29756         local dir=$DIR/$tdir
29757         local numfiles=$((RANDOM % 4096 + 2))
29758         local numblocks=$((RANDOM % 256 + 1))
29759
29760         wait_delete_completed
29761         test_mkdir $dir
29762
29763         # check block output
29764         check_lfs_df blocks $dir
29765         # check inode output
29766         check_lfs_df inodes $dir
29767
29768         # create a single file and retest
29769         echo "Creating a single file and testing"
29770         createmany -o $dir/$tfile- 1 &>/dev/null ||
29771                 error "creating 1 file in $dir failed"
29772         check_lfs_df blocks $dir
29773         check_lfs_df inodes $dir
29774
29775         # create a random number of files
29776         echo "Creating $((numfiles - 1)) files and testing"
29777         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29778                 error "creating $((numfiles - 1)) files in $dir failed"
29779
29780         # write a random number of blocks to the first test file
29781         echo "Writing $numblocks 4K blocks and testing"
29782         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29783                 count=$numblocks &>/dev/null ||
29784                 error "dd to $dir/${tfile}-0 failed"
29785
29786         # retest
29787         check_lfs_df blocks $dir
29788         check_lfs_df inodes $dir
29789
29790         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29791                 error "unlinking $numfiles files in $dir failed"
29792 }
29793 run_test 418 "df and lfs df outputs match"
29794
29795 test_419()
29796 {
29797         local dir=$DIR/$tdir
29798
29799         mkdir -p $dir
29800         touch $dir/file
29801
29802         cancel_lru_locks mdc
29803
29804         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29805         $LCTL set_param fail_loc=0x1410
29806         cat $dir/file
29807         $LCTL set_param fail_loc=0
29808         rm -rf $dir
29809 }
29810 run_test 419 "Verify open file by name doesn't crash kernel"
29811
29812 test_420()
29813 {
29814         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29815                 skip "Need MDS version at least 2.12.53"
29816
29817         local SAVE_UMASK=$(umask)
29818         local dir=$DIR/$tdir
29819         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29820
29821         mkdir -p $dir
29822         umask 0000
29823         mkdir -m03777 $dir/testdir
29824         ls -dn $dir/testdir
29825         # Need to remove trailing '.' when SELinux is enabled
29826         local dirperms=$(ls -dn $dir/testdir |
29827                          awk '{ sub(/\.$/, "", $1); print $1}')
29828         [ $dirperms == "drwxrwsrwt" ] ||
29829                 error "incorrect perms on $dir/testdir"
29830
29831         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29832                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29833         ls -n $dir/testdir/testfile
29834         local fileperms=$(ls -n $dir/testdir/testfile |
29835                           awk '{ sub(/\.$/, "", $1); print $1}')
29836         [ $fileperms == "-rwxr-xr-x" ] ||
29837                 error "incorrect perms on $dir/testdir/testfile"
29838
29839         umask $SAVE_UMASK
29840 }
29841 run_test 420 "clear SGID bit on non-directories for non-members"
29842
29843 test_421a() {
29844         local cnt
29845         local fid1
29846         local fid2
29847
29848         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29849                 skip "Need MDS version at least 2.12.54"
29850
29851         test_mkdir $DIR/$tdir
29852         createmany -o $DIR/$tdir/f 3
29853         cnt=$(ls -1 $DIR/$tdir | wc -l)
29854         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29855
29856         fid1=$(lfs path2fid $DIR/$tdir/f1)
29857         fid2=$(lfs path2fid $DIR/$tdir/f2)
29858         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29859
29860         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29861         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29862
29863         cnt=$(ls -1 $DIR/$tdir | wc -l)
29864         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29865
29866         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29867         createmany -o $DIR/$tdir/f 3
29868         cnt=$(ls -1 $DIR/$tdir | wc -l)
29869         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29870
29871         fid1=$(lfs path2fid $DIR/$tdir/f1)
29872         fid2=$(lfs path2fid $DIR/$tdir/f2)
29873         echo "remove using fsname $FSNAME"
29874         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29875
29876         cnt=$(ls -1 $DIR/$tdir | wc -l)
29877         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29878 }
29879 run_test 421a "simple rm by fid"
29880
29881 test_421b() {
29882         local cnt
29883         local FID1
29884         local FID2
29885
29886         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29887                 skip "Need MDS version at least 2.12.54"
29888
29889         test_mkdir $DIR/$tdir
29890         createmany -o $DIR/$tdir/f 3
29891         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29892         MULTIPID=$!
29893
29894         FID1=$(lfs path2fid $DIR/$tdir/f1)
29895         FID2=$(lfs path2fid $DIR/$tdir/f2)
29896         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29897
29898         kill -USR1 $MULTIPID
29899         wait
29900
29901         cnt=$(ls $DIR/$tdir | wc -l)
29902         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29903 }
29904 run_test 421b "rm by fid on open file"
29905
29906 test_421c() {
29907         local cnt
29908         local FIDS
29909
29910         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29911                 skip "Need MDS version at least 2.12.54"
29912
29913         test_mkdir $DIR/$tdir
29914         createmany -o $DIR/$tdir/f 3
29915         touch $DIR/$tdir/$tfile
29916         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29917         cnt=$(ls -1 $DIR/$tdir | wc -l)
29918         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29919
29920         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29921         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29922
29923         cnt=$(ls $DIR/$tdir | wc -l)
29924         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29925 }
29926 run_test 421c "rm by fid against hardlinked files"
29927
29928 test_421d() {
29929         local cnt
29930         local FIDS
29931
29932         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29933                 skip "Need MDS version at least 2.12.54"
29934
29935         test_mkdir $DIR/$tdir
29936         createmany -o $DIR/$tdir/f 4097
29937         cnt=$(ls -1 $DIR/$tdir | wc -l)
29938         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29939
29940         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29941         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29942
29943         cnt=$(ls $DIR/$tdir | wc -l)
29944         rm -rf $DIR/$tdir
29945         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29946 }
29947 run_test 421d "rmfid en masse"
29948
29949 test_421e() {
29950         local cnt
29951         local FID
29952
29953         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29954         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29955                 skip "Need MDS version at least 2.12.54"
29956
29957         mkdir -p $DIR/$tdir
29958         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29959         createmany -o $DIR/$tdir/striped_dir/f 512
29960         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29961         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29962
29963         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29964                 sed "s/[/][^:]*://g")
29965         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29966
29967         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29968         rm -rf $DIR/$tdir
29969         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29970 }
29971 run_test 421e "rmfid in DNE"
29972
29973 test_421f() {
29974         local cnt
29975         local FID
29976
29977         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29978                 skip "Need MDS version at least 2.12.54"
29979
29980         test_mkdir $DIR/$tdir
29981         touch $DIR/$tdir/f
29982         cnt=$(ls -1 $DIR/$tdir | wc -l)
29983         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29984
29985         FID=$(lfs path2fid $DIR/$tdir/f)
29986         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29987         # rmfid should fail
29988         cnt=$(ls -1 $DIR/$tdir | wc -l)
29989         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29990
29991         chmod a+rw $DIR/$tdir
29992         ls -la $DIR/$tdir
29993         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29994         # rmfid should fail
29995         cnt=$(ls -1 $DIR/$tdir | wc -l)
29996         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29997
29998         rm -f $DIR/$tdir/f
29999         $RUNAS touch $DIR/$tdir/f
30000         FID=$(lfs path2fid $DIR/$tdir/f)
30001         echo "rmfid as root"
30002         $LFS rmfid $DIR $FID || error "rmfid as root failed"
30003         cnt=$(ls -1 $DIR/$tdir | wc -l)
30004         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
30005
30006         rm -f $DIR/$tdir/f
30007         $RUNAS touch $DIR/$tdir/f
30008         cnt=$(ls -1 $DIR/$tdir | wc -l)
30009         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
30010         FID=$(lfs path2fid $DIR/$tdir/f)
30011         # rmfid w/o user_fid2path mount option should fail
30012         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
30013         cnt=$(ls -1 $DIR/$tdir | wc -l)
30014         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
30015
30016         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
30017         stack_trap "rmdir $tmpdir"
30018         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
30019                 error "failed to mount client'"
30020         stack_trap "umount_client $tmpdir"
30021
30022         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
30023         # rmfid should succeed
30024         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
30025         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
30026
30027         # rmfid shouldn't allow to remove files due to dir's permission
30028         chmod a+rwx $tmpdir/$tdir
30029         touch $tmpdir/$tdir/f
30030         ls -la $tmpdir/$tdir
30031         FID=$(lfs path2fid $tmpdir/$tdir/f)
30032         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
30033         return 0
30034 }
30035 run_test 421f "rmfid checks permissions"
30036
30037 test_421g() {
30038         local cnt
30039         local FIDS
30040
30041         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30042         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30043                 skip "Need MDS version at least 2.12.54"
30044
30045         mkdir -p $DIR/$tdir
30046         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30047         createmany -o $DIR/$tdir/striped_dir/f 512
30048         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30049         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30050
30051         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30052                 sed "s/[/][^:]*://g")
30053
30054         rm -f $DIR/$tdir/striped_dir/f1*
30055         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30056         removed=$((512 - cnt))
30057
30058         # few files have been just removed, so we expect
30059         # rmfid to fail on their fids
30060         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30061         [ $removed != $errors ] && error "$errors != $removed"
30062
30063         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30064         rm -rf $DIR/$tdir
30065         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30066 }
30067 run_test 421g "rmfid to return errors properly"
30068
30069 test_421h() {
30070         local mount_other
30071         local mount_ret
30072         local rmfid_ret
30073         local old_fid
30074         local fidA
30075         local fidB
30076         local fidC
30077         local fidD
30078
30079         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30080                 skip "Need MDS version at least 2.15.53"
30081
30082         test_mkdir $DIR/$tdir
30083         test_mkdir $DIR/$tdir/subdir
30084         touch $DIR/$tdir/subdir/file0
30085         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30086         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30087         rm -f $DIR/$tdir/subdir/file0
30088         touch $DIR/$tdir/subdir/fileA
30089         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30090         echo File $DIR/$tdir/subdir/fileA FID $fidA
30091         touch $DIR/$tdir/subdir/fileB
30092         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30093         echo File $DIR/$tdir/subdir/fileB FID $fidB
30094         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30095         touch $DIR/$tdir/subdir/fileC
30096         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30097         echo File $DIR/$tdir/subdir/fileC FID $fidC
30098         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30099         touch $DIR/$tdir/fileD
30100         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30101         echo File $DIR/$tdir/fileD FID $fidD
30102
30103         # mount another client mount point with subdirectory mount
30104         export FILESET=/$tdir/subdir
30105         mount_other=${MOUNT}_other
30106         mount_client $mount_other ${MOUNT_OPTS}
30107         mount_ret=$?
30108         export FILESET=""
30109         (( mount_ret == 0 )) || error "mount $mount_other failed"
30110
30111         echo Removing FIDs:
30112         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30113         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30114         rmfid_ret=$?
30115
30116         umount_client $mount_other || error "umount $mount_other failed"
30117
30118         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30119
30120         # fileA should have been deleted
30121         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30122
30123         # fileB should have been deleted
30124         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30125
30126         # fileC should not have been deleted, fid also exists outside of fileset
30127         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30128
30129         # fileD should not have been deleted, it exists outside of fileset
30130         stat $DIR/$tdir/fileD || error "fileD deleted"
30131 }
30132 run_test 421h "rmfid with fileset mount"
30133
30134 test_422() {
30135         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30136         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30137         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30138         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30139         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30140
30141         local amc=$(at_max_get client)
30142         local amo=$(at_max_get mds1)
30143         local timeout=`lctl get_param -n timeout`
30144
30145         at_max_set 0 client
30146         at_max_set 0 mds1
30147
30148 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30149         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30150                         fail_val=$(((2*timeout + 10)*1000))
30151         touch $DIR/$tdir/d3/file &
30152         sleep 2
30153 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30154         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30155                         fail_val=$((2*timeout + 5))
30156         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30157         local pid=$!
30158         sleep 1
30159         kill -9 $pid
30160         sleep $((2 * timeout))
30161         echo kill $pid
30162         kill -9 $pid
30163         lctl mark touch
30164         touch $DIR/$tdir/d2/file3
30165         touch $DIR/$tdir/d2/file4
30166         touch $DIR/$tdir/d2/file5
30167
30168         wait
30169         at_max_set $amc client
30170         at_max_set $amo mds1
30171
30172         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30173         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30174                 error "Watchdog is always throttled"
30175 }
30176 run_test 422 "kill a process with RPC in progress"
30177
30178 stat_test() {
30179     df -h $MOUNT &
30180     df -h $MOUNT &
30181     df -h $MOUNT &
30182     df -h $MOUNT &
30183     df -h $MOUNT &
30184     df -h $MOUNT &
30185 }
30186
30187 test_423() {
30188     local _stats
30189     # ensure statfs cache is expired
30190     sleep 2;
30191
30192     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30193     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30194
30195     return 0
30196 }
30197 run_test 423 "statfs should return a right data"
30198
30199 test_424() {
30200 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30201         $LCTL set_param fail_loc=0x80000522
30202         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30203         rm -f $DIR/$tfile
30204 }
30205 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30206
30207 test_425() {
30208         test_mkdir -c -1 $DIR/$tdir
30209         $LFS setstripe -c -1 $DIR/$tdir
30210
30211         lru_resize_disable "" 100
30212         stack_trap "lru_resize_enable" EXIT
30213
30214         sleep 5
30215
30216         for i in $(seq $((MDSCOUNT * 125))); do
30217                 local t=$DIR/$tdir/$tfile_$i
30218
30219                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30220                         error_noexit "Create file $t"
30221         done
30222         stack_trap "rm -rf $DIR/$tdir" EXIT
30223
30224         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30225                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30226                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30227
30228                 [ $lock_count -le $lru_size ] ||
30229                         error "osc lock count $lock_count > lru size $lru_size"
30230         done
30231
30232         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30233                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30234                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30235
30236                 [ $lock_count -le $lru_size ] ||
30237                         error "mdc lock count $lock_count > lru size $lru_size"
30238         done
30239 }
30240 run_test 425 "lock count should not exceed lru size"
30241
30242 test_426() {
30243         splice-test -r $DIR/$tfile
30244         splice-test -rd $DIR/$tfile
30245         splice-test $DIR/$tfile
30246         splice-test -d $DIR/$tfile
30247 }
30248 run_test 426 "splice test on Lustre"
30249
30250 test_427() {
30251         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30252         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30253                 skip "Need MDS version at least 2.12.4"
30254         local log
30255
30256         mkdir $DIR/$tdir
30257         mkdir $DIR/$tdir/1
30258         mkdir $DIR/$tdir/2
30259         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30260         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30261
30262         $LFS getdirstripe $DIR/$tdir/1/dir
30263
30264         #first setfattr for creating updatelog
30265         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30266
30267 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30268         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30269         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30270         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30271
30272         sleep 2
30273         fail mds2
30274         wait_recovery_complete mds2 $((2*TIMEOUT))
30275
30276         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30277         echo $log | grep "get update log failed" &&
30278                 error "update log corruption is detected" || true
30279 }
30280 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30281
30282 test_428() {
30283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30284         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30285                               awk '/^max_cached_mb/ { print $2 }')
30286         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30287
30288         $LCTL set_param -n llite.*.max_cached_mb=64
30289
30290         mkdir $DIR/$tdir
30291         $LFS setstripe -c 1 $DIR/$tdir
30292         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30293         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30294         #test write
30295         for f in $(seq 4); do
30296                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30297         done
30298         wait
30299
30300         cancel_lru_locks osc
30301         # Test read
30302         for f in $(seq 4); do
30303                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30304         done
30305         wait
30306 }
30307 run_test 428 "large block size IO should not hang"
30308
30309 test_429() { # LU-7915 / LU-10948
30310         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30311         local testfile=$DIR/$tfile
30312         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30313         local new_flag=1
30314         local first_rpc
30315         local second_rpc
30316         local third_rpc
30317
30318         $LCTL get_param $ll_opencache_threshold_count ||
30319                 skip "client does not have opencache parameter"
30320
30321         set_opencache $new_flag
30322         stack_trap "restore_opencache"
30323         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30324                 error "enable opencache failed"
30325         touch $testfile
30326         # drop MDC DLM locks
30327         cancel_lru_locks mdc
30328         # clear MDC RPC stats counters
30329         $LCTL set_param $mdc_rpcstats=clear
30330
30331         # According to the current implementation, we need to run 3 times
30332         # open & close file to verify if opencache is enabled correctly.
30333         # 1st, RPCs are sent for lookup/open and open handle is released on
30334         #      close finally.
30335         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30336         #      so open handle won't be released thereafter.
30337         # 3rd, No RPC is sent out.
30338         $MULTIOP $testfile oc || error "multiop failed"
30339         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30340         echo "1st: $first_rpc RPCs in flight"
30341
30342         $MULTIOP $testfile oc || error "multiop failed"
30343         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30344         echo "2nd: $second_rpc RPCs in flight"
30345
30346         $MULTIOP $testfile oc || error "multiop failed"
30347         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30348         echo "3rd: $third_rpc RPCs in flight"
30349
30350         #verify no MDC RPC is sent
30351         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30352 }
30353 run_test 429 "verify if opencache flag on client side does work"
30354
30355 lseek_test_430() {
30356         local offset
30357         local file=$1
30358
30359         # data at [200K, 400K)
30360         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30361                 error "256K->512K dd fails"
30362         # data at [2M, 3M)
30363         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30364                 error "2M->3M dd fails"
30365         # data at [4M, 5M)
30366         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30367                 error "4M->5M dd fails"
30368         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30369         # start at first component hole #1
30370         printf "Seeking hole from 1000 ... "
30371         offset=$(lseek_test -l 1000 $file)
30372         echo $offset
30373         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30374         printf "Seeking data from 1000 ... "
30375         offset=$(lseek_test -d 1000 $file)
30376         echo $offset
30377         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30378
30379         # start at first component data block
30380         printf "Seeking hole from 300000 ... "
30381         offset=$(lseek_test -l 300000 $file)
30382         echo $offset
30383         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30384         printf "Seeking data from 300000 ... "
30385         offset=$(lseek_test -d 300000 $file)
30386         echo $offset
30387         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30388
30389         # start at the first component but beyond end of object size
30390         printf "Seeking hole from 1000000 ... "
30391         offset=$(lseek_test -l 1000000 $file)
30392         echo $offset
30393         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30394         printf "Seeking data from 1000000 ... "
30395         offset=$(lseek_test -d 1000000 $file)
30396         echo $offset
30397         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30398
30399         # start at second component stripe 2 (empty file)
30400         printf "Seeking hole from 1500000 ... "
30401         offset=$(lseek_test -l 1500000 $file)
30402         echo $offset
30403         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30404         printf "Seeking data from 1500000 ... "
30405         offset=$(lseek_test -d 1500000 $file)
30406         echo $offset
30407         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30408
30409         # start at second component stripe 1 (all data)
30410         printf "Seeking hole from 3000000 ... "
30411         offset=$(lseek_test -l 3000000 $file)
30412         echo $offset
30413         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30414         printf "Seeking data from 3000000 ... "
30415         offset=$(lseek_test -d 3000000 $file)
30416         echo $offset
30417         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30418
30419         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30420                 error "2nd dd fails"
30421         echo "Add data block at 640K...1280K"
30422
30423         # start at before new data block, in hole
30424         printf "Seeking hole from 600000 ... "
30425         offset=$(lseek_test -l 600000 $file)
30426         echo $offset
30427         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30428         printf "Seeking data from 600000 ... "
30429         offset=$(lseek_test -d 600000 $file)
30430         echo $offset
30431         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30432
30433         # start at the first component new data block
30434         printf "Seeking hole from 1000000 ... "
30435         offset=$(lseek_test -l 1000000 $file)
30436         echo $offset
30437         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30438         printf "Seeking data from 1000000 ... "
30439         offset=$(lseek_test -d 1000000 $file)
30440         echo $offset
30441         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30442
30443         # start at second component stripe 2, new data
30444         printf "Seeking hole from 1200000 ... "
30445         offset=$(lseek_test -l 1200000 $file)
30446         echo $offset
30447         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30448         printf "Seeking data from 1200000 ... "
30449         offset=$(lseek_test -d 1200000 $file)
30450         echo $offset
30451         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30452
30453         # start beyond file end
30454         printf "Using offset > filesize ... "
30455         lseek_test -l 4000000 $file && error "lseek should fail"
30456         printf "Using offset > filesize ... "
30457         lseek_test -d 4000000 $file && error "lseek should fail"
30458
30459         printf "Done\n\n"
30460 }
30461
30462 test_430a() {
30463         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30464                 skip "MDT does not support SEEK_HOLE"
30465
30466         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30467                 skip "OST does not support SEEK_HOLE"
30468
30469         local file=$DIR/$tdir/$tfile
30470
30471         mkdir -p $DIR/$tdir
30472
30473         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30474         # OST stripe #1 will have continuous data at [1M, 3M)
30475         # OST stripe #2 is empty
30476         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30477         lseek_test_430 $file
30478         rm $file
30479         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30480         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30481         lseek_test_430 $file
30482         rm $file
30483         $LFS setstripe -c2 -S 512K $file
30484         echo "Two stripes, stripe size 512K"
30485         lseek_test_430 $file
30486         rm $file
30487         # FLR with stale mirror
30488         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30489                        -N -c2 -S 1M $file
30490         echo "Mirrored file:"
30491         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30492         echo "Plain 2 stripes 1M"
30493         lseek_test_430 $file
30494         rm $file
30495 }
30496 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30497
30498 test_430b() {
30499         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30500                 skip "OST does not support SEEK_HOLE"
30501
30502         local offset
30503         local file=$DIR/$tdir/$tfile
30504
30505         mkdir -p $DIR/$tdir
30506         # Empty layout lseek should fail
30507         $MCREATE $file
30508         # seek from 0
30509         printf "Seeking hole from 0 ... "
30510         lseek_test -l 0 $file && error "lseek should fail"
30511         printf "Seeking data from 0 ... "
30512         lseek_test -d 0 $file && error "lseek should fail"
30513         rm $file
30514
30515         # 1M-hole file
30516         $LFS setstripe -E 1M -c2 -E eof $file
30517         $TRUNCATE $file 1048576
30518         printf "Seeking hole from 1000000 ... "
30519         offset=$(lseek_test -l 1000000 $file)
30520         echo $offset
30521         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30522         printf "Seeking data from 1000000 ... "
30523         lseek_test -d 1000000 $file && error "lseek should fail"
30524         rm $file
30525
30526         # full component followed by non-inited one
30527         $LFS setstripe -E 1M -c2 -E eof $file
30528         dd if=/dev/urandom of=$file bs=1M count=1
30529         printf "Seeking hole from 1000000 ... "
30530         offset=$(lseek_test -l 1000000 $file)
30531         echo $offset
30532         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30533         printf "Seeking hole from 1048576 ... "
30534         lseek_test -l 1048576 $file && error "lseek should fail"
30535         # init second component and truncate back
30536         echo "123" >> $file
30537         $TRUNCATE $file 1048576
30538         printf "Seeking hole from 1000000 ... "
30539         offset=$(lseek_test -l 1000000 $file)
30540         echo $offset
30541         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30542         printf "Seeking hole from 1048576 ... "
30543         lseek_test -l 1048576 $file && error "lseek should fail"
30544         # boundary checks for big values
30545         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30546         offset=$(lseek_test -d 0 $file.10g)
30547         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30548         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30549         offset=$(lseek_test -d 0 $file.100g)
30550         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30551         return 0
30552 }
30553 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30554
30555 test_430c() {
30556         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30557                 skip "OST does not support SEEK_HOLE"
30558
30559         local file=$DIR/$tdir/$tfile
30560         local start
30561
30562         mkdir -p $DIR/$tdir
30563         stack_trap "rm -f $file $file.tmp"
30564         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30565
30566         # cp version 8.33+ prefers lseek over fiemap
30567         local ver=$(cp --version | awk '{ print $4; exit; }')
30568
30569         echo "cp $ver installed"
30570         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30571                 start=$SECONDS
30572                 time cp -v $file $file.tmp || error "cp $file failed"
30573                 (( SECONDS - start < 5 )) || {
30574                         strace cp $file $file.tmp |&
30575                                 grep -E "open|read|seek|FIEMAP" |
30576                                 grep -A 100 $file
30577                         error "cp: too long runtime $((SECONDS - start))"
30578                 }
30579         else
30580                 echo "cp test skipped due to $ver < 8.33"
30581         fi
30582
30583         # tar version 1.29+ supports SEEK_HOLE/DATA
30584         ver=$(tar --version | awk '{ print $4; exit; }')
30585         echo "tar $ver installed"
30586         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30587                 start=$SECONDS
30588                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30589                 (( SECONDS - start < 5 )) || {
30590                         strace tar cf $file.tmp --sparse $file |&
30591                                 grep -E "open|read|seek|FIEMAP" |
30592                                 grep -A 100 $file
30593                         error "tar: too long runtime $((SECONDS - start))"
30594                 }
30595         else
30596                 echo "tar test skipped due to $ver < 1.29"
30597         fi
30598 }
30599 run_test 430c "lseek: external tools check"
30600
30601 test_431() { # LU-14187
30602         local file=$DIR/$tdir/$tfile
30603
30604         mkdir -p $DIR/$tdir
30605         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30606         dd if=/dev/urandom of=$file bs=4k count=1
30607         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30608         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30609         #define OBD_FAIL_OST_RESTART_IO 0x251
30610         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30611         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30612         cp $file $file.0
30613         cancel_lru_locks
30614         sync_all_data
30615         echo 3 > /proc/sys/vm/drop_caches
30616         diff  $file $file.0 || error "data diff"
30617 }
30618 run_test 431 "Restart transaction for IO"
30619
30620 cleanup_test_432() {
30621         do_facet mgs $LCTL nodemap_activate 0
30622         wait_nm_sync active
30623 }
30624
30625 test_432() {
30626         local tmpdir=$TMP/dir432
30627
30628         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30629                 skip "Need MDS version at least 2.14.52"
30630
30631         stack_trap cleanup_test_432 EXIT
30632         mkdir $DIR/$tdir
30633         mkdir $tmpdir
30634
30635         do_facet mgs $LCTL nodemap_activate 1
30636         wait_nm_sync active
30637         do_facet mgs $LCTL nodemap_modify --name default \
30638                 --property admin --value 1
30639         do_facet mgs $LCTL nodemap_modify --name default \
30640                 --property trusted --value 1
30641         cancel_lru_locks mdc
30642         wait_nm_sync default admin_nodemap
30643         wait_nm_sync default trusted_nodemap
30644
30645         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30646                grep -ci "Operation not permitted") -ne 0 ]; then
30647                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30648         fi
30649 }
30650 run_test 432 "mv dir from outside Lustre"
30651
30652 test_433() {
30653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30654
30655         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30656                 skip "inode cache not supported"
30657
30658         $LCTL set_param llite.*.inode_cache=0
30659         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30660
30661         local count=256
30662         local before
30663         local after
30664
30665         cancel_lru_locks mdc
30666         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30667         createmany -m $DIR/$tdir/f $count
30668         createmany -d $DIR/$tdir/d $count
30669         ls -l $DIR/$tdir > /dev/null
30670         stack_trap "rm -rf $DIR/$tdir"
30671
30672         before=$(num_objects)
30673         cancel_lru_locks mdc
30674         after=$(num_objects)
30675
30676         # sometimes even @before is less than 2 * count
30677         while (( before - after < count )); do
30678                 sleep 1
30679                 after=$(num_objects)
30680                 wait=$((wait + 1))
30681                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30682                 if (( wait > 60 )); then
30683                         error "inode slab grew from $before to $after"
30684                 fi
30685         done
30686
30687         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30688 }
30689 run_test 433 "ldlm lock cancel releases dentries and inodes"
30690
30691 test_434() {
30692         local file
30693         local getxattr_count
30694         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30695         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30696
30697         [[ $(getenforce) == "Disabled" ]] ||
30698                 skip "lsm selinux module have to be disabled for this test"
30699
30700         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30701                 error "fail to create $DIR/$tdir/ on MDT0000"
30702
30703         touch $DIR/$tdir/$tfile-{001..100}
30704
30705         # disable the xattr cache
30706         save_lustre_params client "llite.*.xattr_cache" > $p
30707         lctl set_param llite.*.xattr_cache=0
30708         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30709
30710         # clear clients mdc stats
30711         clear_stats $mdc_stat_param ||
30712                 error "fail to clear stats on mdc MDT0000"
30713
30714         for file in $DIR/$tdir/$tfile-{001..100}; do
30715                 getfattr -n security.selinux $file |&
30716                         grep -q "Operation not supported" ||
30717                         error "getxattr on security.selinux should return EOPNOTSUPP"
30718         done
30719
30720         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30721         (( getxattr_count < 100 )) ||
30722                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30723 }
30724 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30725
30726 test_440() {
30727         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30728                 source $LUSTRE/scripts/bash-completion/lustre
30729         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30730                 source /usr/share/bash-completion/completions/lustre
30731         else
30732                 skip "bash completion scripts not found"
30733         fi
30734
30735         local lctl_completions
30736         local lfs_completions
30737
30738         lctl_completions=$(_lustre_cmds lctl)
30739         if [[ ! $lctl_completions =~ "get_param" ]]; then
30740                 error "lctl bash completion failed"
30741         fi
30742
30743         lfs_completions=$(_lustre_cmds lfs)
30744         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30745                 error "lfs bash completion failed"
30746         fi
30747 }
30748 run_test 440 "bash completion for lfs, lctl"
30749
30750 test_442() {
30751         local pid1
30752         local pid2
30753         mkdir -p $DIR/$tdir
30754         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30755         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30756         sleep 1
30757         touch $DIR/$tdir/$tfile.2
30758         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30759         $LCTL set_param fail_loc=0x1430
30760         kill -USR1 $pid1
30761         sleep 1
30762         kill -USR1 $pid2
30763         wait
30764 }
30765 run_test 442 "truncate vs read/write should not panic"
30766
30767 test_460d() {
30768         verify_yaml_available || skip_env "YAML verification not installed"
30769         $LCTL get_param -n sptlrpc.page_pools
30770         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30771                 error "The output of encrypt_page_pools is not an valid YAML"
30772 }
30773 run_test 460d "Check encrypt pools output"
30774
30775 prep_801() {
30776         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30777         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30778                 skip "Need server version at least 2.9.55"
30779
30780         start_full_debug_logging
30781 }
30782
30783 post_801() {
30784         stop_full_debug_logging
30785 }
30786
30787 barrier_stat() {
30788         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30789                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30790                            awk '/The barrier for/ { print $7 }')
30791                 echo $st
30792         else
30793                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30794                 echo \'$st\'
30795         fi
30796 }
30797
30798 barrier_expired() {
30799         local expired
30800
30801         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30802                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30803                           awk '/will be expired/ { print $7 }')
30804         else
30805                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30806         fi
30807
30808         echo $expired
30809 }
30810
30811 test_801a() {
30812         prep_801
30813
30814         echo "Start barrier_freeze at: $(date)"
30815         #define OBD_FAIL_BARRIER_DELAY          0x2202
30816         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30817         # Do not reduce barrier time - See LU-11873
30818         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30819
30820         sleep 2
30821         local b_status=$(barrier_stat)
30822         echo "Got barrier status at: $(date)"
30823         [ "$b_status" = "'freezing_p1'" ] ||
30824                 error "(1) unexpected barrier status $b_status"
30825
30826         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30827         wait
30828         b_status=$(barrier_stat)
30829         [ "$b_status" = "'frozen'" ] ||
30830                 error "(2) unexpected barrier status $b_status"
30831
30832         local expired=$(barrier_expired)
30833         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30834         sleep $((expired + 3))
30835
30836         b_status=$(barrier_stat)
30837         [ "$b_status" = "'expired'" ] ||
30838                 error "(3) unexpected barrier status $b_status"
30839
30840         # Do not reduce barrier time - See LU-11873
30841         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30842                 error "(4) fail to freeze barrier"
30843
30844         b_status=$(barrier_stat)
30845         [ "$b_status" = "'frozen'" ] ||
30846                 error "(5) unexpected barrier status $b_status"
30847
30848         echo "Start barrier_thaw at: $(date)"
30849         #define OBD_FAIL_BARRIER_DELAY          0x2202
30850         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30851         do_facet mgs $LCTL barrier_thaw $FSNAME &
30852
30853         sleep 2
30854         b_status=$(barrier_stat)
30855         echo "Got barrier status at: $(date)"
30856         [ "$b_status" = "'thawing'" ] ||
30857                 error "(6) unexpected barrier status $b_status"
30858
30859         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30860         wait
30861         b_status=$(barrier_stat)
30862         [ "$b_status" = "'thawed'" ] ||
30863                 error "(7) unexpected barrier status $b_status"
30864
30865         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30866         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30867         do_facet mgs $LCTL barrier_freeze $FSNAME
30868
30869         b_status=$(barrier_stat)
30870         [ "$b_status" = "'failed'" ] ||
30871                 error "(8) unexpected barrier status $b_status"
30872
30873         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30874         do_facet mgs $LCTL barrier_thaw $FSNAME
30875
30876         post_801
30877 }
30878 run_test 801a "write barrier user interfaces and stat machine"
30879
30880 test_801b() {
30881         prep_801
30882
30883         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30884         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30885         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30886         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30887         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30888
30889         cancel_lru_locks mdc
30890
30891         # 180 seconds should be long enough
30892         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30893
30894         local b_status=$(barrier_stat)
30895         [ "$b_status" = "'frozen'" ] ||
30896                 error "(6) unexpected barrier status $b_status"
30897
30898         mkdir $DIR/$tdir/d0/d10 &
30899         mkdir_pid=$!
30900
30901         touch $DIR/$tdir/d1/f13 &
30902         touch_pid=$!
30903
30904         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30905         ln_pid=$!
30906
30907         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30908         mv_pid=$!
30909
30910         rm -f $DIR/$tdir/d4/f12 &
30911         rm_pid=$!
30912
30913         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30914
30915         # To guarantee taht the 'stat' is not blocked
30916         b_status=$(barrier_stat)
30917         [ "$b_status" = "'frozen'" ] ||
30918                 error "(8) unexpected barrier status $b_status"
30919
30920         # let above commands to run at background
30921         sleep 5
30922
30923         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30924         ps -p $touch_pid || error "(10) touch should be blocked"
30925         ps -p $ln_pid || error "(11) link should be blocked"
30926         ps -p $mv_pid || error "(12) rename should be blocked"
30927         ps -p $rm_pid || error "(13) unlink should be blocked"
30928
30929         b_status=$(barrier_stat)
30930         [ "$b_status" = "'frozen'" ] ||
30931                 error "(14) unexpected barrier status $b_status"
30932
30933         do_facet mgs $LCTL barrier_thaw $FSNAME
30934         b_status=$(barrier_stat)
30935         [ "$b_status" = "'thawed'" ] ||
30936                 error "(15) unexpected barrier status $b_status"
30937
30938         wait $mkdir_pid || error "(16) mkdir should succeed"
30939         wait $touch_pid || error "(17) touch should succeed"
30940         wait $ln_pid || error "(18) link should succeed"
30941         wait $mv_pid || error "(19) rename should succeed"
30942         wait $rm_pid || error "(20) unlink should succeed"
30943
30944         post_801
30945 }
30946 run_test 801b "modification will be blocked by write barrier"
30947
30948 test_801c() {
30949         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30950
30951         prep_801
30952
30953         stop mds2 || error "(1) Fail to stop mds2"
30954
30955         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30956
30957         local b_status=$(barrier_stat)
30958         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30959                 do_facet mgs $LCTL barrier_thaw $FSNAME
30960                 error "(2) unexpected barrier status $b_status"
30961         }
30962
30963         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30964                 error "(3) Fail to rescan barrier bitmap"
30965
30966         # Do not reduce barrier time - See LU-11873
30967         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30968
30969         b_status=$(barrier_stat)
30970         [ "$b_status" = "'frozen'" ] ||
30971                 error "(4) unexpected barrier status $b_status"
30972
30973         do_facet mgs $LCTL barrier_thaw $FSNAME
30974         b_status=$(barrier_stat)
30975         [ "$b_status" = "'thawed'" ] ||
30976                 error "(5) unexpected barrier status $b_status"
30977
30978         local devname=$(mdsdevname 2)
30979
30980         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30981
30982         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30983                 error "(7) Fail to rescan barrier bitmap"
30984
30985         post_801
30986 }
30987 run_test 801c "rescan barrier bitmap"
30988
30989 test_802b() {
30990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30991         remote_mds_nodsh && skip "remote MDS with nodsh"
30992
30993         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30994                 skip "readonly option not available"
30995
30996         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30997
30998         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30999                 error "(2) Fail to copy"
31000
31001         # write back all cached data before setting MDT to readonly
31002         cancel_lru_locks
31003         sync_all_data
31004
31005         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
31006         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
31007
31008         echo "Modify should be refused"
31009         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
31010
31011         echo "Read should be allowed"
31012         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
31013                 error "(7) Read should succeed under ro mode"
31014
31015         # disable readonly
31016         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
31017 }
31018 run_test 802b "be able to set MDTs to readonly"
31019
31020 test_803a() {
31021         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31022         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31023                 skip "MDS needs to be newer than 2.10.54"
31024
31025         mkdir_on_mdt0 $DIR/$tdir
31026         # Create some objects on all MDTs to trigger related logs objects
31027         for idx in $(seq $MDSCOUNT); do
31028                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
31029                         $DIR/$tdir/dir${idx} ||
31030                         error "Fail to create $DIR/$tdir/dir${idx}"
31031         done
31032
31033         wait_delete_completed # ensure old test cleanups are finished
31034         sleep 3
31035         echo "before create:"
31036         $LFS df -i $MOUNT
31037         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31038
31039         for i in {1..10}; do
31040                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31041                         error "Fail to create $DIR/$tdir/foo$i"
31042         done
31043
31044         # sync ZFS-on-MDS to refresh statfs data
31045         wait_zfs_commit mds1
31046         sleep 3
31047         echo "after create:"
31048         $LFS df -i $MOUNT
31049         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31050
31051         # allow for an llog to be cleaned up during the test
31052         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31053                 error "before ($before_used) + 10 > after ($after_used)"
31054
31055         for i in {1..10}; do
31056                 rm -rf $DIR/$tdir/foo$i ||
31057                         error "Fail to remove $DIR/$tdir/foo$i"
31058         done
31059
31060         # sync ZFS-on-MDS to refresh statfs data
31061         wait_zfs_commit mds1
31062         wait_delete_completed
31063         sleep 3 # avoid MDT return cached statfs
31064         echo "after unlink:"
31065         $LFS df -i $MOUNT
31066         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31067
31068         # allow for an llog to be created during the test
31069         [ $after_used -le $((before_used + 1)) ] ||
31070                 error "after ($after_used) > before ($before_used) + 1"
31071 }
31072 run_test 803a "verify agent object for remote object"
31073
31074 test_803b() {
31075         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31076         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31077                 skip "MDS needs to be newer than 2.13.56"
31078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31079
31080         for i in $(seq 0 $((MDSCOUNT - 1))); do
31081                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31082         done
31083
31084         local before=0
31085         local after=0
31086
31087         local tmp
31088
31089         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31090         for i in $(seq 0 $((MDSCOUNT - 1))); do
31091                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31092                         awk '/getattr/ { print $2 }')
31093                 before=$((before + tmp))
31094         done
31095         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31096         for i in $(seq 0 $((MDSCOUNT - 1))); do
31097                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31098                         awk '/getattr/ { print $2 }')
31099                 after=$((after + tmp))
31100         done
31101
31102         [ $before -eq $after ] || error "getattr count $before != $after"
31103 }
31104 run_test 803b "remote object can getattr from cache"
31105
31106 test_804() {
31107         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31108         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31109                 skip "MDS needs to be newer than 2.10.54"
31110         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31111
31112         mkdir -p $DIR/$tdir
31113         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31114                 error "Fail to create $DIR/$tdir/dir0"
31115
31116         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31117         local dev=$(mdsdevname 2)
31118
31119         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31120                 grep ${fid} || error "NOT found agent entry for dir0"
31121
31122         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31123                 error "Fail to create $DIR/$tdir/dir1"
31124
31125         touch $DIR/$tdir/dir1/foo0 ||
31126                 error "Fail to create $DIR/$tdir/dir1/foo0"
31127         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31128         local rc=0
31129
31130         for idx in $(seq $MDSCOUNT); do
31131                 dev=$(mdsdevname $idx)
31132                 do_facet mds${idx} \
31133                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31134                         grep ${fid} && rc=$idx
31135         done
31136
31137         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31138                 error "Fail to rename foo0 to foo1"
31139         if [ $rc -eq 0 ]; then
31140                 for idx in $(seq $MDSCOUNT); do
31141                         dev=$(mdsdevname $idx)
31142                         do_facet mds${idx} \
31143                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31144                         grep ${fid} && rc=$idx
31145                 done
31146         fi
31147
31148         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31149                 error "Fail to rename foo1 to foo2"
31150         if [ $rc -eq 0 ]; then
31151                 for idx in $(seq $MDSCOUNT); do
31152                         dev=$(mdsdevname $idx)
31153                         do_facet mds${idx} \
31154                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31155                         grep ${fid} && rc=$idx
31156                 done
31157         fi
31158
31159         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31160
31161         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31162                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31163         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31164                 error "Fail to rename foo2 to foo0"
31165         unlink $DIR/$tdir/dir1/foo0 ||
31166                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31167         rm -rf $DIR/$tdir/dir0 ||
31168                 error "Fail to rm $DIR/$tdir/dir0"
31169
31170         for idx in $(seq $MDSCOUNT); do
31171                 rc=0
31172
31173                 stop mds${idx}
31174                 dev=$(mdsdevname $idx)
31175                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31176                         rc=$?
31177                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31178                         error "mount mds$idx failed"
31179                 df $MOUNT > /dev/null 2>&1
31180
31181                 # e2fsck should not return error
31182                 [ $rc -eq 0 ] ||
31183                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31184         done
31185 }
31186 run_test 804 "verify agent entry for remote entry"
31187
31188 cleanup_805() {
31189         do_facet $SINGLEMDS zfs set quota=$old $fsset
31190         unlinkmany $DIR/$tdir/f- 1000000
31191         trap 0
31192 }
31193
31194 test_805() {
31195         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31196         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31197         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31198                 skip "netfree not implemented before 0.7"
31199         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31200                 skip "Need MDS version at least 2.10.57"
31201
31202         local fsset
31203         local freekb
31204         local usedkb
31205         local old
31206         local quota
31207         local pref="osd-zfs.$FSNAME-MDT0000."
31208
31209         # limit available space on MDS dataset to meet nospace issue
31210         # quickly. then ZFS 0.7.2 can use reserved space if asked
31211         # properly (using netfree flag in osd_declare_destroy()
31212         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31213         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31214                 gawk '{print $3}')
31215         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31216         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31217         let "usedkb=usedkb-freekb"
31218         let "freekb=freekb/2"
31219         if let "freekb > 5000"; then
31220                 let "freekb=5000"
31221         fi
31222         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31223         trap cleanup_805 EXIT
31224         mkdir_on_mdt0 $DIR/$tdir
31225         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31226                 error "Can't set PFL layout"
31227         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31228         rm -rf $DIR/$tdir || error "not able to remove"
31229         do_facet $SINGLEMDS zfs set quota=$old $fsset
31230         trap 0
31231 }
31232 run_test 805 "ZFS can remove from full fs"
31233
31234 # Size-on-MDS test
31235 check_lsom_data()
31236 {
31237         local file=$1
31238         local expect=$(stat -c %s $file)
31239         local msg=$2
31240
31241         check_lsom_size $1 $expect $msg
31242
31243         local blocks=$($LFS getsom -b $file)
31244         expect=$(stat -c %b $file)
31245         [[ $blocks == $expect ]] ||
31246                 error "$msg $file expected blocks: $expect, got: $blocks"
31247 }
31248
31249 check_lsom_size()
31250 {
31251         local size
31252         local expect=$2
31253         local msg=$3
31254
31255         cancel_lru_locks mdc
31256
31257         size=$($LFS getsom -s $1)
31258         [[ $size == $expect ]] ||
31259                 error "$msg $file expected size: $expect, got: $size"
31260 }
31261
31262 test_806() {
31263         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31264                 skip "Need MDS version at least 2.11.52"
31265
31266         local bs=1048576
31267
31268         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31269
31270         disable_opencache
31271         stack_trap "restore_opencache"
31272
31273         # single-threaded write
31274         echo "Test SOM for single-threaded write"
31275         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31276                 error "write $tfile failed"
31277         check_lsom_size $DIR/$tfile $bs "(0)"
31278         # Test SOM with DIO write (dd truncates to 0)
31279         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 oflag=direct ||
31280                 error "write $tfile failed"
31281         check_lsom_size $DIR/$tfile $bs "(1)"
31282
31283         local num=32
31284         local size=$(($num * $bs))
31285         local offset=0
31286         local i
31287
31288         echo "Test SOM for single client multi-threaded($num) write"
31289         $TRUNCATE $DIR/$tfile 0
31290         for ((i = 0; i < $num; i++)); do
31291                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31292                 local pids[$i]=$!
31293                 offset=$((offset + $bs))
31294         done
31295         for (( i=0; i < $num; i++ )); do
31296                 wait ${pids[$i]}
31297         done
31298         check_lsom_size $DIR/$tfile $size "(2)"
31299
31300         $TRUNCATE $DIR/$tfile 0
31301         for ((i = 0; i < $num; i++)); do
31302                 offset=$((offset - $bs))
31303                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31304                 local pids[$i]=$!
31305         done
31306         for (( i=0; i < $num; i++ )); do
31307                 wait ${pids[$i]}
31308         done
31309         check_lsom_size $DIR/$tfile $size "(3)"
31310
31311         # multi-client writes
31312         num=$(get_node_count ${CLIENTS//,/ })
31313         size=$(($num * $bs))
31314         offset=0
31315         i=0
31316
31317         echo "Test SOM for multi-client ($num) writes"
31318         $TRUNCATE $DIR/$tfile 0
31319         for client in ${CLIENTS//,/ }; do
31320                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31321                 local pids[$i]=$!
31322                 i=$((i + 1))
31323                 offset=$((offset + $bs))
31324         done
31325         for (( i=0; i < $num; i++ )); do
31326                 wait ${pids[$i]}
31327         done
31328         check_lsom_size $DIR/$tfile $offset "(4)"
31329
31330         i=0
31331         $TRUNCATE $DIR/$tfile 0
31332         for client in ${CLIENTS//,/ }; do
31333                 offset=$((offset - $bs))
31334                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31335                 local pids[$i]=$!
31336                 i=$((i + 1))
31337         done
31338         for (( i=0; i < $num; i++ )); do
31339                 wait ${pids[$i]}
31340         done
31341         check_lsom_size $DIR/$tfile $size "(5)"
31342
31343         # verify SOM blocks count
31344         echo "Verify SOM block count"
31345         $TRUNCATE $DIR/$tfile 0
31346         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31347                 error "failed to write file $tfile with fdatasync and fstat"
31348         check_lsom_data $DIR/$tfile "(6)"
31349
31350         $TRUNCATE $DIR/$tfile 0
31351         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31352                 error "failed to write file $tfile with fdatasync"
31353         check_lsom_data $DIR/$tfile "(7)"
31354
31355         $TRUNCATE $DIR/$tfile 0
31356         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31357                 error "failed to write file $tfile with sync IO"
31358         check_lsom_data $DIR/$tfile "(8)"
31359
31360         # verify truncate
31361         echo "Test SOM for truncate"
31362         # use ftruncate to sync blocks on close request
31363         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31364         check_lsom_size $DIR/$tfile 16384 "(9)"
31365         check_lsom_data $DIR/$tfile "(10)"
31366
31367         $TRUNCATE $DIR/$tfile 1234
31368         check_lsom_size $DIR/$tfile 1234 "(11)"
31369         # sync blocks on the MDT
31370         $MULTIOP $DIR/$tfile oc
31371         check_lsom_data $DIR/$tfile "(12)"
31372 }
31373 run_test 806 "Verify Lazy Size on MDS"
31374
31375 test_807() {
31376         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31377         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31378                 skip "Need MDS version at least 2.11.52"
31379
31380         # Registration step
31381         changelog_register || error "changelog_register failed"
31382         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31383         changelog_users $SINGLEMDS | grep -q $cl_user ||
31384                 error "User $cl_user not found in changelog_users"
31385
31386         rm -rf $DIR/$tdir || error "rm $tdir failed"
31387         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31388         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31389         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31390         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31391                 error "truncate $tdir/trunc failed"
31392
31393         local bs=1048576
31394         echo "Test SOM for single-threaded write with fsync"
31395         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31396                 error "write $tfile failed"
31397         sync;sync;sync
31398
31399         # multi-client wirtes
31400         local num=$(get_node_count ${CLIENTS//,/ })
31401         local offset=0
31402         local i=0
31403
31404         echo "Test SOM for multi-client ($num) writes"
31405         touch $DIR/$tfile || error "touch $tfile failed"
31406         $TRUNCATE $DIR/$tfile 0
31407         for client in ${CLIENTS//,/ }; do
31408                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31409                 local pids[$i]=$!
31410                 i=$((i + 1))
31411                 offset=$((offset + $bs))
31412         done
31413         for (( i=0; i < $num; i++ )); do
31414                 wait ${pids[$i]}
31415         done
31416
31417         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31418         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31419         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31420         check_lsom_data $DIR/$tdir/trunc "(0)"
31421         check_lsom_data $DIR/$tdir/single_dd "(1)"
31422         check_lsom_data $DIR/$tfile "(2)"
31423
31424         rm -rf $DIR/$tdir
31425         # Deregistration step
31426         changelog_deregister || error "changelog_deregister failed"
31427 }
31428 run_test 807 "verify LSOM syncing tool"
31429
31430 check_som_nologged()
31431 {
31432         local lines=$($LFS changelog $FSNAME-MDT0000 |
31433                 grep 'x=trusted.som' | wc -l)
31434         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31435 }
31436
31437 test_808() {
31438         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31439                 skip "Need MDS version at least 2.11.55"
31440
31441         # Registration step
31442         changelog_register || error "changelog_register failed"
31443
31444         touch $DIR/$tfile || error "touch $tfile failed"
31445         check_som_nologged
31446
31447         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31448                 error "write $tfile failed"
31449         check_som_nologged
31450
31451         $TRUNCATE $DIR/$tfile 1234
31452         check_som_nologged
31453
31454         $TRUNCATE $DIR/$tfile 1048576
31455         check_som_nologged
31456
31457         # Deregistration step
31458         changelog_deregister || error "changelog_deregister failed"
31459 }
31460 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31461
31462 check_som_nodata()
31463 {
31464         $LFS getsom $1
31465         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31466 }
31467
31468 test_809() {
31469         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31470                 skip "Need MDS version at least 2.11.56"
31471
31472         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31473                 error "failed to create DoM-only file $DIR/$tfile"
31474         touch $DIR/$tfile || error "touch $tfile failed"
31475         check_som_nodata $DIR/$tfile
31476
31477         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31478                 error "write $tfile failed"
31479         check_som_nodata $DIR/$tfile
31480
31481         $TRUNCATE $DIR/$tfile 1234
31482         check_som_nodata $DIR/$tfile
31483
31484         $TRUNCATE $DIR/$tfile 4097
31485         check_som_nodata $DIR/$file
31486 }
31487 run_test 809 "Verify no SOM xattr store for DoM-only files"
31488
31489 test_810() {
31490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31491         $GSS && skip_env "could not run with gss"
31492         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31493                 skip "OST < 2.12.58 doesn't align checksum"
31494
31495         set_checksums 1
31496         stack_trap "set_checksums $ORIG_CSUM" EXIT
31497         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31498
31499         local csum
31500         local before
31501         local after
31502         for csum in $CKSUM_TYPES; do
31503                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31504                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31505                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31506                         eval set -- $i
31507                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31508                         before=$(md5sum $DIR/$tfile)
31509                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31510                         after=$(md5sum $DIR/$tfile)
31511                         [ "$before" == "$after" ] ||
31512                                 error "$csum: $before != $after bs=$1 seek=$2"
31513                 done
31514         done
31515 }
31516 run_test 810 "partial page writes on ZFS (LU-11663)"
31517
31518 test_812a() {
31519         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31520                 skip "OST < 2.12.51 doesn't support this fail_loc"
31521         local old
31522
31523         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31524         $LCTL set_param osc.*.idle_timeout=10
31525         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31526
31527         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31528         # ensure ost1 is connected
31529         stat $DIR/$tfile >/dev/null || error "can't stat"
31530         wait_osc_import_state client ost1 FULL
31531         # no locks, no reqs to let the connection idle
31532         cancel_lru_locks osc
31533
31534         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31535 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31536         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31537         wait_osc_import_state client ost1 CONNECTING
31538         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31539
31540         stat $DIR/$tfile >/dev/null || error "can't stat file"
31541 }
31542 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31543
31544 test_812b() { # LU-12378
31545         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31546                 skip "OST < 2.12.51 doesn't support this fail_loc"
31547         local old
31548
31549         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31550         $LCTL set_param osc.*.idle_timeout=10
31551         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31552
31553         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31554         # ensure ost1 is connected
31555         stat $DIR/$tfile >/dev/null || error "can't stat"
31556         wait_osc_import_state client ost1 FULL
31557         # no locks, no reqs to let the connection idle
31558         cancel_lru_locks osc
31559
31560         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31561 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31562         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31563         wait_osc_import_state client ost1 CONNECTING
31564         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31565
31566         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31567         wait_osc_import_state client ost1 IDLE
31568 }
31569 run_test 812b "do not drop no resend request for idle connect"
31570
31571 test_812c() {
31572         local old
31573
31574         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31575
31576         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31577         $LFS getstripe $DIR/$tfile
31578         $LCTL set_param osc.*.idle_timeout=10
31579         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31580         # ensure ost1 is connected
31581         stat $DIR/$tfile >/dev/null || error "can't stat"
31582         wait_osc_import_state client ost1 FULL
31583         # no locks, no reqs to let the connection idle
31584         cancel_lru_locks osc
31585
31586 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31587         $LCTL set_param fail_loc=0x80000533
31588         sleep 15
31589         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31590 }
31591 run_test 812c "idle import vs lock enqueue race"
31592
31593 test_813() {
31594         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31595         [ -z "$file_heat_sav" ] && skip "no file heat support"
31596
31597         local readsample
31598         local writesample
31599         local readbyte
31600         local writebyte
31601         local readsample1
31602         local writesample1
31603         local readbyte1
31604         local writebyte1
31605
31606         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31607         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31608
31609         $LCTL set_param -n llite.*.file_heat=1
31610         echo "Turn on file heat"
31611         echo "Period second: $period_second, Decay percentage: $decay_pct"
31612
31613         echo "QQQQ" > $DIR/$tfile
31614         echo "QQQQ" > $DIR/$tfile
31615         echo "QQQQ" > $DIR/$tfile
31616         cat $DIR/$tfile > /dev/null
31617         cat $DIR/$tfile > /dev/null
31618         cat $DIR/$tfile > /dev/null
31619         cat $DIR/$tfile > /dev/null
31620
31621         local out=$($LFS heat_get $DIR/$tfile)
31622
31623         $LFS heat_get $DIR/$tfile
31624         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31625         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31626         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31627         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31628
31629         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31630         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31631         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31632         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31633
31634         sleep $((period_second + 3))
31635         echo "Sleep $((period_second + 3)) seconds..."
31636         # The recursion formula to calculate the heat of the file f is as
31637         # follow:
31638         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31639         # Where Hi is the heat value in the period between time points i*I and
31640         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31641         # to the weight of Ci.
31642         out=$($LFS heat_get $DIR/$tfile)
31643         $LFS heat_get $DIR/$tfile
31644         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31645         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31646         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31647         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31648
31649         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31650                 error "read sample ($readsample) is wrong"
31651         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31652                 error "write sample ($writesample) is wrong"
31653         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31654                 error "read bytes ($readbyte) is wrong"
31655         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31656                 error "write bytes ($writebyte) is wrong"
31657
31658         echo "QQQQ" > $DIR/$tfile
31659         echo "QQQQ" > $DIR/$tfile
31660         echo "QQQQ" > $DIR/$tfile
31661         cat $DIR/$tfile > /dev/null
31662         cat $DIR/$tfile > /dev/null
31663         cat $DIR/$tfile > /dev/null
31664         cat $DIR/$tfile > /dev/null
31665
31666         sleep $((period_second + 3))
31667         echo "Sleep $((period_second + 3)) seconds..."
31668
31669         out=$($LFS heat_get $DIR/$tfile)
31670         $LFS heat_get $DIR/$tfile
31671         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31672         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31673         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31674         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31675
31676         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31677                 4 * $decay_pct) / 100") -eq 1 ] ||
31678                 error "read sample ($readsample1) is wrong"
31679         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31680                 3 * $decay_pct) / 100") -eq 1 ] ||
31681                 error "write sample ($writesample1) is wrong"
31682         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31683                 20 * $decay_pct) / 100") -eq 1 ] ||
31684                 error "read bytes ($readbyte1) is wrong"
31685         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31686                 15 * $decay_pct) / 100") -eq 1 ] ||
31687                 error "write bytes ($writebyte1) is wrong"
31688
31689         echo "Turn off file heat for the file $DIR/$tfile"
31690         $LFS heat_set -o $DIR/$tfile
31691
31692         echo "QQQQ" > $DIR/$tfile
31693         echo "QQQQ" > $DIR/$tfile
31694         echo "QQQQ" > $DIR/$tfile
31695         cat $DIR/$tfile > /dev/null
31696         cat $DIR/$tfile > /dev/null
31697         cat $DIR/$tfile > /dev/null
31698         cat $DIR/$tfile > /dev/null
31699
31700         out=$($LFS heat_get $DIR/$tfile)
31701         $LFS heat_get $DIR/$tfile
31702         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31703         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31704         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31705         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31706
31707         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31708         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31709         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31710         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31711
31712         echo "Trun on file heat for the file $DIR/$tfile"
31713         $LFS heat_set -O $DIR/$tfile
31714
31715         echo "QQQQ" > $DIR/$tfile
31716         echo "QQQQ" > $DIR/$tfile
31717         echo "QQQQ" > $DIR/$tfile
31718         cat $DIR/$tfile > /dev/null
31719         cat $DIR/$tfile > /dev/null
31720         cat $DIR/$tfile > /dev/null
31721         cat $DIR/$tfile > /dev/null
31722
31723         out=$($LFS heat_get $DIR/$tfile)
31724         $LFS heat_get $DIR/$tfile
31725         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31726         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31727         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31728         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31729
31730         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31731         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31732         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31733         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31734
31735         $LFS heat_set -c $DIR/$tfile
31736         $LCTL set_param -n llite.*.file_heat=0
31737         echo "Turn off file heat support for the Lustre filesystem"
31738
31739         echo "QQQQ" > $DIR/$tfile
31740         echo "QQQQ" > $DIR/$tfile
31741         echo "QQQQ" > $DIR/$tfile
31742         cat $DIR/$tfile > /dev/null
31743         cat $DIR/$tfile > /dev/null
31744         cat $DIR/$tfile > /dev/null
31745         cat $DIR/$tfile > /dev/null
31746
31747         out=$($LFS heat_get $DIR/$tfile)
31748         $LFS heat_get $DIR/$tfile
31749         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31750         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31751         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31752         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31753
31754         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31755         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31756         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31757         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31758
31759         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31760         rm -f $DIR/$tfile
31761 }
31762 run_test 813 "File heat verfication"
31763
31764 test_814()
31765 {
31766         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31767         echo -n y >> $DIR/$tfile
31768         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31769         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31770 }
31771 run_test 814 "sparse cp works as expected (LU-12361)"
31772
31773 test_815()
31774 {
31775         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31776         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31777 }
31778 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31779
31780 test_816() {
31781         local ost1_imp=$(get_osc_import_name client ost1)
31782         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31783                          cut -d'.' -f2)
31784         local old
31785
31786         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31787         $LCTL set_param osc.*.idle_timeout=10
31788         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31789
31790         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31791         # ensure ost1 is connected
31792
31793         stat $DIR/$tfile >/dev/null || error "can't stat"
31794         wait_osc_import_state client ost1 FULL
31795         # no locks, no reqs to let the connection idle
31796         cancel_lru_locks osc
31797         lru_resize_disable osc
31798         local before
31799         local now
31800         before=$($LCTL get_param -n \
31801                  ldlm.namespaces.$imp_name.lru_size)
31802
31803         wait_osc_import_state client ost1 IDLE
31804         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31805         now=$($LCTL get_param -n \
31806               ldlm.namespaces.$imp_name.lru_size)
31807         [ $before == $now ] || error "lru_size changed $before != $now"
31808 }
31809 run_test 816 "do not reset lru_resize on idle reconnect"
31810
31811 cleanup_817() {
31812         umount $tmpdir
31813         exportfs -u localhost:$DIR/nfsexp
31814         rm -rf $DIR/nfsexp
31815 }
31816
31817 test_817() {
31818         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31819
31820         mkdir -p $DIR/nfsexp
31821         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31822                 error "failed to export nfs"
31823
31824         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31825         stack_trap cleanup_817 EXIT
31826
31827         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31828                 error "failed to mount nfs to $tmpdir"
31829
31830         cp /bin/true $tmpdir
31831         $DIR/nfsexp/true || error "failed to execute 'true' command"
31832 }
31833 run_test 817 "nfsd won't cache write lock for exec file"
31834
31835 test_818() {
31836         test_mkdir -i0 -c1 $DIR/$tdir
31837         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31838         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31839         stop $SINGLEMDS
31840
31841         # restore osp-syn threads
31842         stack_trap "fail $SINGLEMDS"
31843
31844         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31845         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31846         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31847                 error "start $SINGLEMDS failed"
31848         rm -rf $DIR/$tdir
31849
31850         local testid=$(echo $TESTNAME | tr '_' ' ')
31851
31852         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31853                 grep "run LFSCK" || error "run LFSCK is not suggested"
31854 }
31855 run_test 818 "unlink with failed llog"
31856
31857 test_819a() {
31858         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31859         cancel_lru_locks osc
31860         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31861         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31862         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31863         rm -f $TDIR/$tfile
31864 }
31865 run_test 819a "too big niobuf in read"
31866
31867 test_819b() {
31868         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31869         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31870         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31871         cancel_lru_locks osc
31872         sleep 1
31873         rm -f $TDIR/$tfile
31874 }
31875 run_test 819b "too big niobuf in write"
31876
31877
31878 function test_820_start_ost() {
31879         sleep 5
31880
31881         for num in $(seq $OSTCOUNT); do
31882                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31883         done
31884 }
31885
31886 test_820() {
31887         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31888
31889         mkdir $DIR/$tdir
31890         umount_client $MOUNT || error "umount failed"
31891         for num in $(seq $OSTCOUNT); do
31892                 stop ost$num
31893         done
31894
31895         # mount client with no active OSTs
31896         # so that the client can't initialize max LOV EA size
31897         # from OSC notifications
31898         mount_client $MOUNT || error "mount failed"
31899         # delay OST starting to keep this 0 max EA size for a while
31900         test_820_start_ost &
31901
31902         # create a directory on MDS2
31903         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31904                 error "Failed to create directory"
31905         # open intent should update default EA size
31906         # see mdc_update_max_ea_from_body()
31907         # notice this is the very first RPC to MDS2
31908         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31909         ret=$?
31910         echo $out
31911         # With SSK, this situation can lead to -EPERM being returned.
31912         # In that case, simply retry.
31913         if [ $ret -ne 0 ] && $SHARED_KEY; then
31914                 if echo "$out" | grep -q "not permitted"; then
31915                         cp /etc/services $DIR/$tdir/mds2
31916                         ret=$?
31917                 fi
31918         fi
31919         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31920 }
31921 run_test 820 "update max EA from open intent"
31922
31923 test_823() {
31924         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31925         local OST_MAX_PRECREATE=20000
31926
31927         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31928                 skip "Need MDS version at least 2.14.56"
31929
31930         save_lustre_params mds1 \
31931                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31932         do_facet $SINGLEMDS "$LCTL set_param -n \
31933                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31934         do_facet $SINGLEMDS "$LCTL set_param -n \
31935                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31936
31937         stack_trap "restore_lustre_params < $p; rm $p"
31938
31939         do_facet $SINGLEMDS "$LCTL set_param -n \
31940                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31941
31942         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31943                       osp.$FSNAME-OST0000*MDT0000.create_count")
31944         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31945                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31946         local expect_count=$(((($max/2)/256) * 256))
31947
31948         log "setting create_count to 100200:"
31949         log " -result- count: $count with max: $max, expecting: $expect_count"
31950
31951         [[ $count -eq expect_count ]] ||
31952                 error "Create count not set to max precreate."
31953 }
31954 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31955
31956 test_831() {
31957         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31958                 skip "Need MDS version 2.14.56"
31959
31960         local sync_changes=$(do_facet $SINGLEMDS \
31961                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31962
31963         [ "$sync_changes" -gt 100 ] &&
31964                 skip "Sync changes $sync_changes > 100 already"
31965
31966         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31967
31968         $LFS mkdir -i 0 $DIR/$tdir
31969         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31970
31971         save_lustre_params mds1 \
31972                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31973         save_lustre_params mds1 \
31974                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31975
31976         do_facet mds1 "$LCTL set_param -n \
31977                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31978                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31979         stack_trap "restore_lustre_params < $p" EXIT
31980
31981         createmany -o $DIR/$tdir/f- 1000
31982         unlinkmany $DIR/$tdir/f- 1000 &
31983         local UNLINK_PID=$!
31984
31985         while sleep 1; do
31986                 sync_changes=$(do_facet mds1 \
31987                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31988                 # the check in the code is racy, fail the test
31989                 # if the value above the limit by 10.
31990                 [ $sync_changes -gt 110 ] && {
31991                         kill -2 $UNLINK_PID
31992                         wait
31993                         error "osp changes throttling failed, $sync_changes>110"
31994                 }
31995                 kill -0 $UNLINK_PID 2> /dev/null || break
31996         done
31997         wait
31998 }
31999 run_test 831 "throttling unlink/setattr queuing on OSP"
32000
32001 test_832() {
32002         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32003         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
32004                 skip "Need MDS version 2.15.52+"
32005         is_rmentry_supported || skip "rm_entry not supported"
32006
32007         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
32008         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
32009         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
32010                 error "mkdir remote_dir failed"
32011         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
32012                 error "mkdir striped_dir failed"
32013         touch $DIR/$tdir/file || error "touch file failed"
32014         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
32015         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
32016 }
32017 run_test 832 "lfs rm_entry"
32018
32019 test_833() {
32020         local file=$DIR/$tfile
32021
32022         stack_trap "rm -f $file" EXIT
32023         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
32024
32025         local wpid
32026         local rpid
32027         local rpid2
32028
32029         # Buffered I/O write
32030         (
32031                 while [ ! -e $DIR/sanity.833.lck ]; do
32032                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
32033                                 error "failed to write $file"
32034                         sleep 0.$((RANDOM % 4 + 1))
32035                 done
32036         )&
32037         wpid=$!
32038
32039         # Buffered I/O read
32040         (
32041                 while [ ! -e $DIR/sanity.833.lck ]; do
32042                         dd if=$file of=/dev/null bs=1M count=50 ||
32043                                 error "failed to read $file"
32044                         sleep 0.$((RANDOM % 4 + 1))
32045                 done
32046         )&
32047         rpid=$!
32048
32049         # Direct I/O read
32050         (
32051                 while [ ! -e $DIR/sanity.833.lck ]; do
32052                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32053                                 error "failed to read $file in direct I/O mode"
32054                         sleep 0.$((RANDOM % 4 + 1))
32055                 done
32056         )&
32057         rpid2=$!
32058
32059         sleep 30
32060         touch $DIR/sanity.833.lck
32061         wait $wpid || error "$?: buffered write failed"
32062         wait $rpid || error "$?: buffered read failed"
32063         wait $rpid2 || error "$?: direct read failed"
32064 }
32065 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32066
32067 test_842() {
32068         local oss1=$(facet_host ost1)
32069
32070         # Try to insert the module.  This will leave results in dmesg
32071         now=$(date +%s)
32072         log "STAMP $now" > /dev/kmsg
32073         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32074                 error "$oss1 load_module ldlm_extent failed"
32075
32076         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32077         do_node $oss1 rmmod -v ldlm_extent ||
32078                 error "rmmod failed (may trigger a failure in a later test)"
32079 }
32080 run_test 842 "Measure ldlm_extent performance"
32081
32082 test_850() {
32083         local dir=$DIR/$tdir
32084         local file=$dir/$tfile
32085         local statsfile=$dir/all_job_stats.txt
32086
32087         test_mkdir -p $dir || error "failed to create dir $dir"
32088         echo "abcdefg" > $file || error "failed to create file $file"
32089
32090         # read job_stats in the living system
32091         lljobstat -n 1 ||
32092                 error "failed to run lljobstat on living system"
32093
32094         $LCTL get_param *.*.job_stats > $statsfile
32095         lljobstat --statsfile=$statsfile ||
32096                 error "failed to run lljobstat on file $statsfile"
32097 }
32098 run_test 850 "lljobstat can parse living and aggregated job_stats"
32099
32100 test_851() {
32101         local dir=$DIR/$tdir
32102         local file=$dir/f_test_851_$$
32103         local report=/tmp/report_test_851_$$
32104         local fanotify_prog=monitor_lustrefs
32105         local pid
32106
32107         test_mkdir $dir || error "failed to create dir $dir"
32108
32109         $fanotify_prog $DIR > $report &
32110         pid=$!
32111
32112         sleep 1
32113         if ! kill -0 $pid; then
32114                 error "failed to start $fanoify_prog"
32115         fi
32116
32117         stack_trap "kill $pid"
32118         stack_trap "rm -f $report"
32119
32120         echo "1234567890" > $file
32121         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32122                 error "fanotify did not report anything after 30 seconds"
32123         grep -a -E "open.*:$file:" $report ||
32124                 error "no open event for writing $file"
32125         grep -a -E "write.*:$file:" $report ||
32126                 error "no write event for writing $file"
32127         grep -a -E "close.*:$file:" $report ||
32128                 error "no close event for writing $file"
32129
32130         > $report
32131         cat $file
32132         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32133                 error "fanotify did not report anything after 30 seconds"
32134         grep -a -E "open.*:$file:" $report ||
32135                 error "no open event for reading $file"
32136         grep -a -E "read.*:$file:" $report ||
32137                 error "no write event for reading $file"
32138         grep -a -E "close.*:$file:" $report ||
32139                 error "no close event for reading $file"
32140 }
32141 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32142
32143 #
32144 # tests that do cleanup/setup should be run at the end
32145 #
32146
32147 test_900() {
32148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32149         local ls
32150
32151         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32152         $LCTL set_param fail_loc=0x903
32153
32154         cancel_lru_locks MGC
32155
32156         FAIL_ON_ERROR=true cleanup
32157         FAIL_ON_ERROR=true setup
32158 }
32159 run_test 900 "umount should not race with any mgc requeue thread"
32160
32161 # LUS-6253/LU-11185
32162 test_901() {
32163         local old
32164         local count
32165         local oldc
32166         local newc
32167         local olds
32168         local news
32169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32170
32171         # some get_param have a bug to handle dot in param name
32172         cancel_lru_locks MGC
32173         old=$(mount -t lustre | wc -l)
32174         # 1 config+sptlrpc
32175         # 2 params
32176         # 3 nodemap
32177         # 4 IR
32178         old=$((old * 4))
32179         oldc=0
32180         count=0
32181         while [ $old -ne $oldc ]; do
32182                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32183                 sleep 1
32184                 ((count++))
32185                 if [ $count -ge $TIMEOUT ]; then
32186                         error "too large timeout"
32187                 fi
32188         done
32189         umount_client $MOUNT || error "umount failed"
32190         mount_client $MOUNT || error "mount failed"
32191         cancel_lru_locks MGC
32192         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32193
32194         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32195
32196         return 0
32197 }
32198 run_test 901 "don't leak a mgc lock on client umount"
32199
32200 # LU-13377
32201 test_902() {
32202         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32203                 skip "client does not have LU-13377 fix"
32204         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32205         $LCTL set_param fail_loc=0x1415
32206         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32207         cancel_lru_locks osc
32208         rm -f $DIR/$tfile
32209 }
32210 run_test 902 "test short write doesn't hang lustre"
32211
32212 # LU-14711
32213 test_903() {
32214         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32215         echo "blah" > $DIR/${tfile}-2
32216         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32217         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32218         $LCTL set_param fail_loc=0x417 fail_val=20
32219
32220         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32221         sleep 1 # To start the destroy
32222         wait_destroy_complete 150 || error "Destroy taking too long"
32223         cat $DIR/$tfile > /dev/null || error "Evicted"
32224 }
32225 run_test 903 "Test long page discard does not cause evictions"
32226
32227 test_904() {
32228         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32229         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32230                 grep -q project || skip "skip project quota not supported"
32231
32232         local testfile="$DIR/$tdir/$tfile"
32233         local xattr="trusted.projid"
32234         local projid
32235         local mdts=$(comma_list $(mdts_nodes))
32236         local saved=$(do_facet mds1 $LCTL get_param -n \
32237                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32238
32239         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32240         stack_trap "do_nodes $mdts $LCTL set_param \
32241                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32242
32243         mkdir -p $DIR/$tdir
32244         touch $testfile
32245         #hide projid xattr on server
32246         $LFS project -p 1 $testfile ||
32247                 error "set $testfile project id failed"
32248         getfattr -m - $testfile | grep $xattr &&
32249                 error "do not show trusted.projid when disabled on server"
32250         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32251         #should be hidden when projid is 0
32252         $LFS project -p 0 $testfile ||
32253                 error "set $testfile project id failed"
32254         getfattr -m - $testfile | grep $xattr &&
32255                 error "do not show trusted.projid with project ID 0"
32256
32257         #still can getxattr explicitly
32258         projid=$(getfattr -n $xattr $testfile |
32259                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32260         [ $projid == "0" ] ||
32261                 error "projid expected 0 not $projid"
32262
32263         #set the projid via setxattr
32264         setfattr -n $xattr -v "1000" $testfile ||
32265                 error "setattr failed with $?"
32266         projid=($($LFS project $testfile))
32267         [ ${projid[0]} == "1000" ] ||
32268                 error "projid expected 1000 not $projid"
32269
32270         #check the new projid via getxattr
32271         $LFS project -p 1001 $testfile ||
32272                 error "set $testfile project id failed"
32273         getfattr -m - $testfile | grep $xattr ||
32274                 error "should show trusted.projid when project ID != 0"
32275         projid=$(getfattr -n $xattr $testfile |
32276                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32277         [ $projid == "1001" ] ||
32278                 error "projid expected 1001 not $projid"
32279
32280         #try to set invalid projid
32281         setfattr -n $xattr -v "4294967295" $testfile &&
32282                 error "set invalid projid should fail"
32283
32284         #remove the xattr means setting projid to 0
32285         setfattr -x $xattr $testfile ||
32286                 error "setfattr failed with $?"
32287         projid=($($LFS project $testfile))
32288         [ ${projid[0]} == "0" ] ||
32289                 error "projid expected 0 not $projid"
32290
32291         #should be hidden when parent has inherit flag and same projid
32292         $LFS project -srp 1002 $DIR/$tdir ||
32293                 error "set $tdir project id failed"
32294         getfattr -m - $testfile | grep $xattr &&
32295                 error "do not show trusted.projid with inherit flag"
32296
32297         #still can getxattr explicitly
32298         projid=$(getfattr -n $xattr $testfile |
32299                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32300         [ $projid == "1002" ] ||
32301                 error "projid expected 1002 not $projid"
32302 }
32303 run_test 904 "virtual project ID xattr"
32304
32305 # LU-8582
32306 test_905() {
32307         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32308                 skip "need OST version >= 2.15.50.220 for fail_loc"
32309
32310         remote_ost_nodsh && skip "remote OST with nodsh"
32311         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32312
32313         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32314
32315         #define OBD_FAIL_OST_OPCODE 0x253
32316         # OST_LADVISE = 21
32317         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32318         $LFS ladvise -a willread $DIR/$tfile &&
32319                 error "unexpected success of ladvise with fault injection"
32320         $LFS ladvise -a willread $DIR/$tfile |&
32321                 grep -q "Operation not supported"
32322         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32323 }
32324 run_test 905 "bad or new opcode should not stuck client"
32325
32326 test_906() {
32327         grep -q io_uring_setup /proc/kallsyms ||
32328                 skip "Client OS does not support io_uring I/O engine"
32329         io_uring_probe || skip "kernel does not support io_uring fully"
32330         which fio || skip_env "no fio installed"
32331         fio --enghelp | grep -q io_uring ||
32332                 skip_env "fio does not support io_uring I/O engine"
32333
32334         local file=$DIR/$tfile
32335         local ioengine="io_uring"
32336         local numjobs=2
32337         local size=50M
32338
32339         fio --name=seqwrite --ioengine=$ioengine        \
32340                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32341                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32342                 error "fio seqwrite $file failed"
32343
32344         fio --name=seqread --ioengine=$ioengine \
32345                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32346                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32347                 error "fio seqread $file failed"
32348
32349         rm -f $file || error "rm -f $file failed"
32350 }
32351 run_test 906 "Simple test for io_uring I/O engine via fio"
32352
32353 test_907() {
32354         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32355
32356         # set stripe size to max rpc size
32357         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32358         $LFS getstripe $DIR/$tfile
32359 #define OBD_FAIL_OST_EROFS               0x216
32360         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32361
32362         local bs=$((max_pages * PAGE_SIZE / 16))
32363
32364         # write full one stripe and one block
32365         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32366
32367         rm $DIR/$tfile || error "rm failed"
32368 }
32369 run_test 907 "write rpc error during unlink"
32370
32371 complete_test $SECONDS
32372 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32373 check_and_cleanup_lustre
32374 if [ "$I_MOUNTED" != "yes" ]; then
32375         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32376 fi
32377 exit_status