Whamcloud - gitweb
7fd3bd2d4becf5ae53ce15f9e5ee8714836184a2
[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_123j() {
14880         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
14881
14882         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14883                 skip "Server does not support batch RPC"
14884
14885         local enabled
14886
14887         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14888         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14889         $LCTL set_param llite.*.enable_statahead_fname=1
14890
14891         stack_trap "rm -rf $DIR/${tdir}.{1..11}"
14892
14893         mkdir $DIR/${tdir}.{1..10} ||
14894                 error "failed to mkdir $DIR/${tdir}.{1..10}"
14895         cancel_lru_locks mdc
14896
14897         for i in $(seq 1 10); do
14898                 stat $DIR/${tdir}.$i || error "failed to stat $DIR/${tdir}.$i"
14899         done
14900
14901         stat $DIR/${tdir}.11
14902         $LFS mkdir -i $((MDSCOUNT - 1)) -c 2 -H all_char $DIR/${tdir}.11 ||
14903                 error "failed to mkdir $DIR/${tdir}.11"
14904         touch $DIR/${tdir}.11/$tfile ||
14905                 error "failed to create file $DIR/${tdir}.11/$tfile"
14906 }
14907 run_test 123j "-ENOENT error from batched statahead be handled correctly"
14908
14909 test_123k() {
14910         MDTEST=${MDTEST:=$(which mdtest 2> /dev/null || true)}
14911         [[ -n "$MDTEST" ]] || skip_env "mdtest not found"
14912
14913         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14914                 skip "Server does not support batch RPC"
14915
14916         local enabled
14917
14918         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14919         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14920         $LCTL set_param llite.*.enable_statahead_fname=1
14921
14922         local np=2
14923
14924         mpi_run -np $np $MDTEST -C -F -n 1000 -d $DIR/$tdir
14925         cancel_lru_locks mdc
14926         $LCTL set_param llite.*.statahead_stats=clear
14927         $LCTL set_param mdc.*.batch_stats=0
14928         mpi_run -np $np $MDTEST -T -F -n 1000 -d $DIR/$tdir
14929         #umount_client $MOUNT || error "failed to umount client"
14930         echo "Sleep to wait statahead thread (ll_sa_xxx) to exit ..."
14931         wait_update_facet client "pgrep ll_sa" "" 35 ||
14932                 error "ll_sa thread is still running"
14933
14934         $LCTL get_param -n llite.*.statahead_stats
14935         $LCTL get_param -n mdc.*.batch_stats
14936         ps -el | grep ll_sa
14937
14938         local count=$($LCTL get_param -n llite.*.statahead_stats |
14939                         awk '/fname.total:/ {print $2}')
14940
14941         [ $count == $np ] || error "File name pattern statahead not trigger"
14942         count=$($LCTL get_param -n llite.*.statahead_stats |
14943                 awk '/hit.total:/ {print $2}')
14944         # Hit ratio should be >= 75%
14945         [ $count -gt $((np * 1000 * 75 / 100)) ] ||
14946                 error "hit total is too low: $count"
14947 }
14948 run_test 123k "Verify statahead work with mdtest shared stat() mode"
14949
14950 test_123l() {
14951         local dir=$DIR/$tdir
14952         local cmd="touch $dir/$tfile.{000000..000100}"
14953
14954         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14955                 skip "Server does not support batch RPC"
14956
14957         stack_trap "rm -rf $dir"
14958         mkdir -p $dir || error "failed to mkdir $dir"
14959         eval $cmd
14960
14961         cancel_lru_locks mdc
14962         $LCTL set_param llite.*.statahead_stats=clear
14963         $LCTL set_param mdc.*.batch_stats=0
14964
14965         local max
14966         local batch_max
14967         local enabled
14968
14969         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14970         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14971         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14972         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14973         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14974         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14975         $LCTL set_param llite.*.enable_statahead_fname=1
14976         $LCTL set_param llite.*.statahead_max=1024
14977         $LCTL set_param llite.*.statahead_batch_max=32
14978         $LCTL get_param -n llite.*.statahead_stats
14979         #define OBD_FAIL_LLITE_STATAHEAD_PAUSE  0x1433
14980         $LCTL set_param fail_loc=0x80001433 fail_val=35
14981         ls $dir/* > /dev/null
14982         $LCTL get_param -n llite.*.statahead_stats
14983         $LCTL get_param -n mdc.*.batch_stats
14984
14985         echo "Sleep to wait the statahead thread (ll_sa_xxx) to exit ..."
14986         wait_update_facet client "pgrep ll_sa" "" 35 ||
14987                 error "ll_sa thread is still running"
14988         $LCTL get_param -n llite.*.statahead_stats
14989 }
14990 run_test 123l "Avoid panic when revalidate a local cached entry"
14991
14992 test_124a() {
14993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14994         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14995                 skip_env "no lru resize on server"
14996
14997         local NR=2000
14998
14999         test_mkdir $DIR/$tdir
15000
15001         log "create $NR files at $DIR/$tdir"
15002         createmany -o $DIR/$tdir/f $NR ||
15003                 error "failed to create $NR files in $DIR/$tdir"
15004
15005         cancel_lru_locks mdc
15006         ls -l $DIR/$tdir > /dev/null
15007
15008         local NSDIR=""
15009         local LRU_SIZE=0
15010         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
15011                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
15012                 LRU_SIZE=$($LCTL get_param -n $PARAM)
15013                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
15014                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
15015                         log "NSDIR=$NSDIR"
15016                         log "NS=$(basename $NSDIR)"
15017                         break
15018                 fi
15019         done
15020
15021         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
15022                 skip "Not enough cached locks created!"
15023         fi
15024         log "LRU=$LRU_SIZE"
15025
15026         local SLEEP=30
15027
15028         # We know that lru resize allows one client to hold $LIMIT locks
15029         # for 10h. After that locks begin to be killed by client.
15030         local MAX_HRS=10
15031         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
15032         log "LIMIT=$LIMIT"
15033         if [ $LIMIT -lt $LRU_SIZE ]; then
15034                 skip "Limit is too small $LIMIT"
15035         fi
15036
15037         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
15038         # killing locks. Some time was spent for creating locks. This means
15039         # that up to the moment of sleep finish we must have killed some of
15040         # them (10-100 locks). This depends on how fast ther were created.
15041         # Many of them were touched in almost the same moment and thus will
15042         # be killed in groups.
15043         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
15044
15045         # Use $LRU_SIZE_B here to take into account real number of locks
15046         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
15047         local LRU_SIZE_B=$LRU_SIZE
15048         log "LVF=$LVF"
15049         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
15050         log "OLD_LVF=$OLD_LVF"
15051         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
15052
15053         # Let's make sure that we really have some margin. Client checks
15054         # cached locks every 10 sec.
15055         SLEEP=$((SLEEP+20))
15056         log "Sleep ${SLEEP} sec"
15057         local SEC=0
15058         while ((SEC<$SLEEP)); do
15059                 echo -n "..."
15060                 sleep 5
15061                 SEC=$((SEC+5))
15062                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
15063                 echo -n "$LRU_SIZE"
15064         done
15065         echo ""
15066         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
15067         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
15068
15069         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
15070                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
15071                 unlinkmany $DIR/$tdir/f $NR
15072                 return
15073         }
15074
15075         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
15076         log "unlink $NR files at $DIR/$tdir"
15077         unlinkmany $DIR/$tdir/f $NR
15078 }
15079 run_test 124a "lru resize ======================================="
15080
15081 get_max_pool_limit()
15082 {
15083         local limit=$($LCTL get_param \
15084                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
15085         local max=0
15086         for l in $limit; do
15087                 if [[ $l -gt $max ]]; then
15088                         max=$l
15089                 fi
15090         done
15091         echo $max
15092 }
15093
15094 test_124b() {
15095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15096         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15097                 skip_env "no lru resize on server"
15098
15099         LIMIT=$(get_max_pool_limit)
15100
15101         NR=$(($(default_lru_size)*20))
15102         if [[ $NR -gt $LIMIT ]]; then
15103                 log "Limit lock number by $LIMIT locks"
15104                 NR=$LIMIT
15105         fi
15106
15107         IFree=$(mdsrate_inodes_available)
15108         if [ $IFree -lt $NR ]; then
15109                 log "Limit lock number by $IFree inodes"
15110                 NR=$IFree
15111         fi
15112
15113         lru_resize_disable mdc
15114         test_mkdir -p $DIR/$tdir/disable_lru_resize
15115
15116         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
15117         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
15118         cancel_lru_locks mdc
15119         stime=`date +%s`
15120         PID=""
15121         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15122         PID="$PID $!"
15123         sleep 2
15124         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15125         PID="$PID $!"
15126         sleep 2
15127         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15128         PID="$PID $!"
15129         wait $PID
15130         etime=`date +%s`
15131         nolruresize_delta=$((etime-stime))
15132         log "ls -la time: $nolruresize_delta seconds"
15133         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15134         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
15135
15136         lru_resize_enable mdc
15137         test_mkdir -p $DIR/$tdir/enable_lru_resize
15138
15139         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
15140         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
15141         cancel_lru_locks mdc
15142         stime=`date +%s`
15143         PID=""
15144         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15145         PID="$PID $!"
15146         sleep 2
15147         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15148         PID="$PID $!"
15149         sleep 2
15150         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15151         PID="$PID $!"
15152         wait $PID
15153         etime=`date +%s`
15154         lruresize_delta=$((etime-stime))
15155         log "ls -la time: $lruresize_delta seconds"
15156         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15157
15158         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15159                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15160         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15161                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15162         else
15163                 log "lru resize performs the same with no lru resize"
15164         fi
15165         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15166 }
15167 run_test 124b "lru resize (performance test) ======================="
15168
15169 test_124c() {
15170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15171         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15172                 skip_env "no lru resize on server"
15173
15174         # cache ununsed locks on client
15175         local nr=100
15176         cancel_lru_locks mdc
15177         test_mkdir $DIR/$tdir
15178         createmany -o $DIR/$tdir/f $nr ||
15179                 error "failed to create $nr files in $DIR/$tdir"
15180         ls -l $DIR/$tdir > /dev/null
15181
15182         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15183         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15184         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15185         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15186         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15187
15188         # set lru_max_age to 1 sec
15189         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15190         echo "sleep $((recalc_p * 2)) seconds..."
15191         sleep $((recalc_p * 2))
15192
15193         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15194         # restore lru_max_age
15195         $LCTL set_param -n $nsdir.lru_max_age $max_age
15196         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15197         unlinkmany $DIR/$tdir/f $nr
15198 }
15199 run_test 124c "LRUR cancel very aged locks"
15200
15201 test_124d() {
15202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15203         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15204                 skip_env "no lru resize on server"
15205
15206         # cache ununsed locks on client
15207         local nr=100
15208
15209         lru_resize_disable mdc
15210         stack_trap "lru_resize_enable mdc" EXIT
15211
15212         cancel_lru_locks mdc
15213
15214         # asynchronous object destroy at MDT could cause bl ast to client
15215         test_mkdir $DIR/$tdir
15216         createmany -o $DIR/$tdir/f $nr ||
15217                 error "failed to create $nr files in $DIR/$tdir"
15218         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15219
15220         ls -l $DIR/$tdir > /dev/null
15221
15222         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15223         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15224         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15225         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15226
15227         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15228
15229         # set lru_max_age to 1 sec
15230         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15231         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15232
15233         echo "sleep $((recalc_p * 2)) seconds..."
15234         sleep $((recalc_p * 2))
15235
15236         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15237
15238         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15239 }
15240 run_test 124d "cancel very aged locks if lru-resize disabled"
15241
15242 test_125() { # 13358
15243         $LCTL get_param -n llite.*.client_type | grep -q local ||
15244                 skip "must run as local client"
15245         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15246                 skip_env "must have acl enabled"
15247         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15248         id $USER0 || skip_env "missing user $USER0"
15249
15250         test_mkdir $DIR/$tdir
15251         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15252         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15253                 error "setfacl $DIR/$tdir failed"
15254         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15255 }
15256 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15257
15258 test_126() { # bug 12829/13455
15259         $GSS && skip_env "must run as gss disabled"
15260         $LCTL get_param -n llite.*.client_type | grep -q local ||
15261                 skip "must run as local client"
15262         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15263
15264         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15265         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15266         rm -f $DIR/$tfile
15267         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15268 }
15269 run_test 126 "check that the fsgid provided by the client is taken into account"
15270
15271 test_127a() { # bug 15521
15272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15273         local name count samp unit min max sum sumsq
15274         local tmpfile=$TMP/$tfile.tmp
15275
15276         # enable stats header if it is disabled
15277         $LCTL set_param enable_stats_header=1
15278
15279         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15280         echo "stats before reset"
15281         stack_trap "rm -f $tmpfile"
15282         local now=$(date +%s)
15283
15284         $LCTL get_param osc.*.stats | tee $tmpfile
15285
15286         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15287         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15288         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15289         local uptime=$(awk '{ print $1 }' /proc/uptime)
15290
15291         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15292         (( ${snapshot_time%\.*} >= $now - 5 &&
15293            ${snapshot_time%\.*} <= $now + 5 )) ||
15294                 error "snapshot_time=$snapshot_time != now=$now"
15295         # elapsed _should_ be from mount, but at least less than uptime
15296         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15297                 error "elapsed=$elapsed > uptime=$uptime"
15298         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15299            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15300                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15301
15302         $LCTL set_param osc.*.stats=0
15303         local reset=$(date +%s)
15304         local fsize=$((2048 * 1024))
15305
15306         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15307         cancel_lru_locks osc
15308         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15309
15310         now=$(date +%s)
15311         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15312         while read name count samp unit min max sum sumsq; do
15313                 [[ "$samp" == "samples" ]] || continue
15314
15315                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15316                 [ ! $min ] && error "Missing min value for $name proc entry"
15317                 eval $name=$count || error "Wrong proc format"
15318
15319                 case $name in
15320                 read_bytes|write_bytes)
15321                         [[ "$unit" =~ "bytes" ]] ||
15322                                 error "unit is not 'bytes': $unit"
15323                         (( $min >= 4096 )) || error "min is too small: $min"
15324                         (( $min <= $fsize )) || error "min is too big: $min"
15325                         (( $max >= 4096 )) || error "max is too small: $max"
15326                         (( $max <= $fsize )) || error "max is too big: $max"
15327                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15328                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15329                                 error "sumsquare is too small: $sumsq"
15330                         (( $sumsq <= $fsize * $fsize )) ||
15331                                 error "sumsquare is too big: $sumsq"
15332                         ;;
15333                 ost_read|ost_write)
15334                         [[ "$unit" =~ "usec" ]] ||
15335                                 error "unit is not 'usec': $unit"
15336                         ;;
15337                 *)      ;;
15338                 esac
15339         done < $tmpfile
15340
15341         #check that we actually got some stats
15342         [ "$read_bytes" ] || error "Missing read_bytes stats"
15343         [ "$write_bytes" ] || error "Missing write_bytes stats"
15344         [ "$read_bytes" != 0 ] || error "no read done"
15345         [ "$write_bytes" != 0 ] || error "no write done"
15346
15347         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15348         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15349         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15350
15351         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15352         (( ${snapshot_time%\.*} >= $now - 5 &&
15353            ${snapshot_time%\.*} <= $now + 5 )) ||
15354                 error "reset snapshot_time=$snapshot_time != now=$now"
15355         # elapsed should be from time of stats reset
15356         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15357            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15358                 error "reset elapsed=$elapsed > $now - $reset"
15359         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15360            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15361                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15362 }
15363 run_test 127a "verify the client stats are sane"
15364
15365 test_127b() { # bug LU-333
15366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15367         local name count samp unit min max sum sumsq
15368
15369         echo "stats before reset"
15370         $LCTL get_param llite.*.stats
15371         $LCTL set_param llite.*.stats=0
15372
15373         # perform 2 reads and writes so MAX is different from SUM.
15374         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15375         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15376         cancel_lru_locks osc
15377         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15378         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15379
15380         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15381         stack_trap "rm -f $TMP/$tfile.tmp"
15382         while read name count samp unit min max sum sumsq; do
15383                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15384                 eval $name=$count || error "Wrong proc format"
15385
15386                 case $name in
15387                 read_bytes|write_bytes)
15388                         [[ "$unit" =~ "bytes" ]] ||
15389                                 error "unit is not 'bytes': $unit"
15390                         (( $count == 2 )) || error "count is not 2: $count"
15391                         (( $min == $PAGE_SIZE )) ||
15392                                 error "min is not $PAGE_SIZE: $min"
15393                         (( $max == $PAGE_SIZE )) ||
15394                                 error "max is not $PAGE_SIZE: $max"
15395                         (( $sum == $PAGE_SIZE * 2 )) ||
15396                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15397                         ;;
15398                 read|write)
15399                         [[ "$unit" =~ "usec" ]] ||
15400                                 error "unit is not 'usec': $unit"
15401                         ;;
15402                 *)      ;;
15403                 esac
15404         done < $TMP/$tfile.tmp
15405
15406         #check that we actually got some stats
15407         [ "$read_bytes" ] || error "Missing read_bytes stats"
15408         [ "$write_bytes" ] || error "Missing write_bytes stats"
15409         [ "$read_bytes" != 0 ] || error "no read done"
15410         [ "$write_bytes" != 0 ] || error "no write done"
15411 }
15412 run_test 127b "verify the llite client stats are sane"
15413
15414 test_127c() { # LU-12394
15415         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15416         local size
15417         local bsize
15418         local reads
15419         local writes
15420         local count
15421
15422         $LCTL set_param llite.*.extents_stats=1
15423         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15424
15425         # Use two stripes so there is enough space in default config
15426         $LFS setstripe -c 2 $DIR/$tfile
15427
15428         # Extent stats start at 0-4K and go in power of two buckets
15429         # LL_HIST_START = 12 --> 2^12 = 4K
15430         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15431         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15432         # small configs
15433         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15434                 do
15435                 # Write and read, 2x each, second time at a non-zero offset
15436                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15437                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15438                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15439                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15440                 rm -f $DIR/$tfile
15441         done
15442
15443         $LCTL get_param llite.*.extents_stats
15444
15445         count=2
15446         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15447                 do
15448                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15449                                 grep -m 1 $bsize)
15450                 reads=$(echo $bucket | awk '{print $5}')
15451                 writes=$(echo $bucket | awk '{print $9}')
15452                 [ "$reads" -eq $count ] ||
15453                         error "$reads reads in < $bsize bucket, expect $count"
15454                 [ "$writes" -eq $count ] ||
15455                         error "$writes writes in < $bsize bucket, expect $count"
15456         done
15457
15458         # Test mmap write and read
15459         $LCTL set_param llite.*.extents_stats=c
15460         size=512
15461         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15462         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15463         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15464
15465         $LCTL get_param llite.*.extents_stats
15466
15467         count=$(((size*1024) / PAGE_SIZE))
15468
15469         bsize=$((2 * PAGE_SIZE / 1024))K
15470
15471         bucket=$($LCTL get_param -n llite.*.extents_stats |
15472                         grep -m 1 $bsize)
15473         reads=$(echo $bucket | awk '{print $5}')
15474         writes=$(echo $bucket | awk '{print $9}')
15475         # mmap writes fault in the page first, creating an additonal read
15476         [ "$reads" -eq $((2 * count)) ] ||
15477                 error "$reads reads in < $bsize bucket, expect $count"
15478         [ "$writes" -eq $count ] ||
15479                 error "$writes writes in < $bsize bucket, expect $count"
15480 }
15481 run_test 127c "test llite extent stats with regular & mmap i/o"
15482
15483 test_128() { # bug 15212
15484         touch $DIR/$tfile
15485         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15486                 find $DIR/$tfile
15487                 find $DIR/$tfile
15488         EOF
15489
15490         result=$(grep error $TMP/$tfile.log)
15491         rm -f $DIR/$tfile $TMP/$tfile.log
15492         [ -z "$result" ] ||
15493                 error "consecutive find's under interactive lfs failed"
15494 }
15495 run_test 128 "interactive lfs for 2 consecutive find's"
15496
15497 set_dir_limits () {
15498         local mntdev
15499         local canondev
15500         local node
15501
15502         local ldproc=/proc/fs/ldiskfs
15503         local facets=$(get_facets MDS)
15504
15505         for facet in ${facets//,/ }; do
15506                 canondev=$(ldiskfs_canon \
15507                            *.$(convert_facet2label $facet).mntdev $facet)
15508                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15509                         ldproc=/sys/fs/ldiskfs
15510                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15511                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15512         done
15513 }
15514
15515 check_mds_dmesg() {
15516         local facets=$(get_facets MDS)
15517         for facet in ${facets//,/ }; do
15518                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15519         done
15520         return 1
15521 }
15522
15523 test_129() {
15524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15525         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15526                 skip "Need MDS version with at least 2.5.56"
15527         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15528                 skip_env "ldiskfs only test"
15529         fi
15530         remote_mds_nodsh && skip "remote MDS with nodsh"
15531
15532         local ENOSPC=28
15533         local has_warning=false
15534
15535         rm -rf $DIR/$tdir
15536         mkdir -p $DIR/$tdir
15537
15538         # block size of mds1
15539         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15540         set_dir_limits $maxsize $((maxsize * 6 / 8))
15541         stack_trap "set_dir_limits 0 0"
15542         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15543         local dirsize=$(stat -c%s "$DIR/$tdir")
15544         local nfiles=0
15545         while (( $dirsize <= $maxsize )); do
15546                 $MCREATE $DIR/$tdir/file_base_$nfiles
15547                 rc=$?
15548                 # check two errors:
15549                 # ENOSPC for ext4 max_dir_size, which has been used since
15550                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15551                 if (( rc == ENOSPC )); then
15552                         set_dir_limits 0 0
15553                         echo "rc=$rc returned as expected after $nfiles files"
15554
15555                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15556                                 error "create failed w/o dir size limit"
15557
15558                         # messages may be rate limited if test is run repeatedly
15559                         check_mds_dmesg '"is approaching max"' ||
15560                                 echo "warning message should be output"
15561                         check_mds_dmesg '"has reached max"' ||
15562                                 echo "reached message should be output"
15563
15564                         dirsize=$(stat -c%s "$DIR/$tdir")
15565
15566                         [[ $dirsize -ge $maxsize ]] && return 0
15567                         error "dirsize $dirsize < $maxsize after $nfiles files"
15568                 elif (( rc != 0 )); then
15569                         break
15570                 fi
15571                 nfiles=$((nfiles + 1))
15572                 dirsize=$(stat -c%s "$DIR/$tdir")
15573         done
15574
15575         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15576 }
15577 run_test 129 "test directory size limit ========================"
15578
15579 OLDIFS="$IFS"
15580 cleanup_130() {
15581         trap 0
15582         IFS="$OLDIFS"
15583         rm -f $DIR/$tfile
15584 }
15585
15586 test_130a() {
15587         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15588         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15589
15590         trap cleanup_130 EXIT RETURN
15591
15592         local fm_file=$DIR/$tfile
15593         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15594         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15595                 error "dd failed for $fm_file"
15596
15597         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15598         filefrag -ves $fm_file
15599         local rc=$?
15600         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15601                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15602         (( $rc == 0 )) || error "filefrag $fm_file failed"
15603
15604         filefrag_op=$(filefrag -ve -k $fm_file |
15605                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15606         local lun=$($LFS getstripe -i $fm_file)
15607
15608         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15609         IFS=$'\n'
15610         local tot_len=0
15611         for line in $filefrag_op; do
15612                 local frag_lun=$(echo $line | cut -d: -f5)
15613                 local ext_len=$(echo $line | cut -d: -f4)
15614
15615                 if (( $frag_lun != $lun )); then
15616                         error "FIEMAP on 1-stripe file($fm_file) failed"
15617                         return
15618                 fi
15619                 (( tot_len += ext_len ))
15620         done
15621
15622         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15623                 error "FIEMAP on 1-stripe file($fm_file) failed"
15624                 return
15625         fi
15626
15627         echo "FIEMAP on single striped file succeeded"
15628 }
15629 run_test 130a "FIEMAP (1-stripe file)"
15630
15631 test_130b() {
15632         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15633
15634         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15635         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15636         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15637                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15638
15639         trap cleanup_130 EXIT RETURN
15640
15641         local fm_file=$DIR/$tfile
15642         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15643                 error "setstripe on $fm_file"
15644
15645         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15646                 error "dd failed on $fm_file"
15647
15648         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15649         filefrag_op=$(filefrag -ve -k $fm_file |
15650                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15651
15652         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15653                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15654
15655         IFS=$'\n'
15656         local tot_len=0
15657         local num_luns=1
15658
15659         for line in $filefrag_op; do
15660                 local frag_lun=$(echo $line | cut -d: -f5 |
15661                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15662                 local ext_len=$(echo $line | cut -d: -f4)
15663                 if (( $frag_lun != $last_lun )); then
15664                         if (( tot_len != 1024 )); then
15665                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15666                                 return
15667                         else
15668                                 (( num_luns += 1 ))
15669                                 tot_len=0
15670                         fi
15671                 fi
15672                 (( tot_len += ext_len ))
15673                 last_lun=$frag_lun
15674         done
15675         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15676                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15677                 return
15678         fi
15679
15680         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15681 }
15682 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15683
15684 test_130c() {
15685         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15686
15687         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15688         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15689         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15690                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15691
15692         trap cleanup_130 EXIT RETURN
15693
15694         local fm_file=$DIR/$tfile
15695         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15696
15697         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15698                 error "dd failed on $fm_file"
15699
15700         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15701         filefrag_op=$(filefrag -ve -k $fm_file |
15702                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15703
15704         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15705                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
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                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15713                 local ext_len=$(echo $line | cut -d: -f4)
15714                 if (( $frag_lun != $last_lun )); then
15715                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15716                         if (( logical != 512 )); then
15717                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15718                                 return
15719                         fi
15720                         if (( tot_len != 512 )); then
15721                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15722                                 return
15723                         else
15724                                 (( num_luns += 1 ))
15725                                 tot_len=0
15726                         fi
15727                 fi
15728                 (( tot_len += ext_len ))
15729                 last_lun=$frag_lun
15730         done
15731         if (( num_luns != 2 || tot_len != 512 )); then
15732                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15733                 return
15734         fi
15735
15736         echo "FIEMAP on 2-stripe file with hole succeeded"
15737 }
15738 run_test 130c "FIEMAP (2-stripe file with hole)"
15739
15740 test_130d() {
15741         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15742
15743         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15744         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15745         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15746                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15747
15748         trap cleanup_130 EXIT RETURN
15749
15750         local fm_file=$DIR/$tfile
15751         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15752                         error "setstripe on $fm_file"
15753
15754         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15755         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15756                 error "dd failed on $fm_file"
15757
15758         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15759         filefrag_op=$(filefrag -ve -k $fm_file |
15760                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15761
15762         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15763                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15764
15765         IFS=$'\n'
15766         local tot_len=0
15767         local num_luns=1
15768         for line in $filefrag_op; do
15769                 local frag_lun=$(echo $line | cut -d: -f5 |
15770                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15771                 local ext_len=$(echo $line | cut -d: -f4)
15772                 if (( $frag_lun != $last_lun )); then
15773                         if (( tot_len != 1024 )); then
15774                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15775                                 return
15776                         else
15777                                 (( num_luns += 1 ))
15778                                 local tot_len=0
15779                         fi
15780                 fi
15781                 (( tot_len += ext_len ))
15782                 last_lun=$frag_lun
15783         done
15784         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15785                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15786                 return
15787         fi
15788
15789         echo "FIEMAP on N-stripe file succeeded"
15790 }
15791 run_test 130d "FIEMAP (N-stripe file)"
15792
15793 test_130e() {
15794         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15795
15796         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15797         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15798         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15799                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15800
15801         trap cleanup_130 EXIT RETURN
15802
15803         local fm_file=$DIR/$tfile
15804         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15805         stack_trap "rm -f $fm_file"
15806
15807         local num_blks=512
15808         local expected_len=$(( (num_blks / 2) * 64 ))
15809         for ((i = 0; i < $num_blks; i++)); do
15810                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15811                         conv=notrunc > /dev/null 2>&1
15812         done
15813
15814         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15815         filefrag_op=$(filefrag -ve -k $fm_file |
15816                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15817
15818         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15819
15820         IFS=$'\n'
15821         local tot_len=0
15822         local num_luns=1
15823         for line in $filefrag_op; do
15824                 local frag_lun=$(echo $line | cut -d: -f5)
15825                 local ext_len=$(echo $line | cut -d: -f4)
15826                 if (( $frag_lun != $last_lun )); then
15827                         if (( tot_len != $expected_len )); then
15828                                 error "OST$last_lun $tot_len != $expected_len"
15829                         else
15830                                 (( num_luns += 1 ))
15831                                 tot_len=0
15832                         fi
15833                 fi
15834                 (( tot_len += ext_len ))
15835                 last_lun=$frag_lun
15836         done
15837         if (( num_luns != 2 || tot_len != $expected_len )); then
15838                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15839         fi
15840
15841         echo "FIEMAP with continuation calls succeeded"
15842 }
15843 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15844
15845 test_130f() {
15846         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15847         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15848         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15849                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15850
15851         local fm_file=$DIR/$tfile
15852         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15853                 error "multiop create with lov_delay_create on $fm_file"
15854
15855         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15856         filefrag_extents=$(filefrag -vek $fm_file |
15857                            awk '/extents? found/ { print $2 }')
15858         if (( $filefrag_extents != 0 )); then
15859                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15860         fi
15861
15862         rm -f $fm_file
15863 }
15864 run_test 130f "FIEMAP (unstriped file)"
15865
15866 test_130g() {
15867         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15868                 skip "Need MDS version with at least 2.12.53 for overstriping"
15869         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15870         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15871         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15872                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15873
15874         local file=$DIR/$tfile
15875         local nr=$((OSTCOUNT * 100))
15876
15877         $LFS setstripe -C $nr -S1M $file ||
15878                 error "failed to setstripe -C $nr $file"
15879
15880         stack_trap "rm -f $file"
15881         dd if=/dev/zero of=$file count=$nr bs=1M
15882         sync
15883         nr=$($LFS getstripe -c $file)
15884
15885         local extents=$(filefrag -v $file |
15886                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15887
15888         echo "filefrag list $extents extents in file with stripecount $nr"
15889         if (( extents < nr )); then
15890                 $LFS getstripe $file
15891                 filefrag -v $file
15892                 error "filefrag printed $extents < $nr extents"
15893         fi
15894 }
15895 run_test 130g "FIEMAP (overstripe file)"
15896
15897 # Test for writev/readv
15898 test_131a() {
15899         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15900                 error "writev test failed"
15901         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15902                 error "readv failed"
15903         rm -f $DIR/$tfile
15904 }
15905 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15906
15907 test_131b() {
15908         local fsize=$((524288 + 1048576 + 1572864))
15909         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15910                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15911                         error "append writev test failed"
15912
15913         ((fsize += 1572864 + 1048576))
15914         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15915                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15916                         error "append writev test failed"
15917         rm -f $DIR/$tfile
15918 }
15919 run_test 131b "test append writev"
15920
15921 test_131c() {
15922         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15923         error "NOT PASS"
15924 }
15925 run_test 131c "test read/write on file w/o objects"
15926
15927 test_131d() {
15928         rwv -f $DIR/$tfile -w -n 1 1572864
15929         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15930         if [ "$NOB" != 1572864 ]; then
15931                 error "Short read filed: read $NOB bytes instead of 1572864"
15932         fi
15933         rm -f $DIR/$tfile
15934 }
15935 run_test 131d "test short read"
15936
15937 test_131e() {
15938         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15939         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15940         error "read hitting hole failed"
15941         rm -f $DIR/$tfile
15942 }
15943 run_test 131e "test read hitting hole"
15944
15945 check_stats() {
15946         local facet=$1
15947         local op=$2
15948         local want=${3:-0}
15949         local res
15950
15951         # open             11 samples [usecs] 468 4793 13658 35791898
15952         case $facet in
15953         mds*) res=($(do_facet $facet \
15954                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15955                  ;;
15956         ost*) res=($(do_facet $facet \
15957                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15958                  ;;
15959         *) error "Wrong facet '$facet'" ;;
15960         esac
15961         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15962         # if $want is zero, it means any stat increment is ok.
15963         if (( $want > 0 )); then
15964                 local count=${res[1]}
15965
15966                 if (( $count != $want )); then
15967                         if [[ $facet =~ "mds" ]]; then
15968                                 do_nodes $(comma_list $(mdts_nodes)) \
15969                                         $LCTL get_param mdt.*.md_stats
15970                         else
15971                                 do_nodes $(comma_list $(osts-nodes)) \
15972                                         $LCTL get_param obdfilter.*.stats
15973                         fi
15974                         error "The $op counter on $facet is $count, not $want"
15975                 fi
15976         fi
15977 }
15978
15979 test_133a() {
15980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15981         remote_ost_nodsh && skip "remote OST with nodsh"
15982         remote_mds_nodsh && skip "remote MDS with nodsh"
15983         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15984                 skip_env "MDS doesn't support rename stats"
15985
15986         local testdir=$DIR/${tdir}/stats_testdir
15987
15988         mkdir_on_mdt0 $DIR/${tdir}
15989
15990         # clear stats.
15991         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15992         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15993
15994         # verify mdt stats first.
15995         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15996         check_stats $SINGLEMDS "mkdir" 1
15997
15998         # clear "open" from "lfs mkdir" above
15999         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16000         touch ${testdir}/${tfile} || error "touch failed"
16001         check_stats $SINGLEMDS "open" 1
16002         check_stats $SINGLEMDS "close" 1
16003         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
16004                 # open should match close
16005                 ls -lR ${testdir}
16006                 check_stats $SINGLEMDS "open" 2
16007                 check_stats $SINGLEMDS "close" 2
16008         }
16009         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
16010                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
16011                 check_stats $SINGLEMDS "mknod" 2
16012         }
16013         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
16014         check_stats $SINGLEMDS "unlink" 1
16015         rm -f ${testdir}/${tfile} || error "file remove failed"
16016         check_stats $SINGLEMDS "unlink" 2
16017
16018         # remove working dir and check mdt stats again.
16019         rmdir ${testdir} || error "rmdir failed"
16020         check_stats $SINGLEMDS "rmdir" 1
16021
16022         local testdir1=$DIR/${tdir}/stats_testdir1
16023         mkdir_on_mdt0 ${testdir}
16024         mkdir_on_mdt0 ${testdir1}
16025         touch ${testdir1}/test1
16026         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
16027         check_stats $SINGLEMDS "crossdir_rename" 1
16028
16029         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
16030         check_stats $SINGLEMDS "samedir_rename" 1
16031
16032         rm -rf $DIR/${tdir}
16033 }
16034 run_test 133a "Verifying MDT stats ========================================"
16035
16036 test_133b() {
16037         local res
16038
16039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16040         remote_ost_nodsh && skip "remote OST with nodsh"
16041         remote_mds_nodsh && skip "remote MDS with nodsh"
16042
16043         local testdir=$DIR/${tdir}/stats_testdir
16044
16045         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16046         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
16047         touch ${testdir}/${tfile} || error "touch failed"
16048         cancel_lru_locks mdc
16049
16050         # clear stats.
16051         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16052         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16053
16054         # extra mdt stats verification.
16055         chmod 444 ${testdir}/${tfile} || error "chmod failed"
16056         check_stats $SINGLEMDS "setattr" 1
16057         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16058         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
16059         then            # LU-1740
16060                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
16061                 check_stats $SINGLEMDS "getattr" 1
16062         fi
16063         rm -rf $DIR/${tdir}
16064
16065         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
16066         # so the check below is not reliable
16067         [ $MDSCOUNT -eq 1 ] || return 0
16068
16069         # Sleep to avoid a cached response.
16070         #define OBD_STATFS_CACHE_SECONDS 1
16071         sleep 2
16072         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16073         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
16074         $LFS df || error "lfs failed"
16075         check_stats $SINGLEMDS "statfs" 1
16076
16077         # check aggregated statfs (LU-10018)
16078         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
16079                 return 0
16080         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
16081                 return 0
16082         sleep 2
16083         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16084         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
16085         df $DIR
16086         check_stats $SINGLEMDS "statfs" 1
16087
16088         # We want to check that the client didn't send OST_STATFS to
16089         # ost1 but the MDT also uses OST_STATFS for precreate. So some
16090         # extra care is needed here.
16091         if remote_mds; then
16092                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
16093                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
16094
16095                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
16096                 [ "$res" ] && error "OST got STATFS"
16097         fi
16098
16099         return 0
16100 }
16101 run_test 133b "Verifying extra MDT stats =================================="
16102
16103 test_133c() {
16104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16105         remote_ost_nodsh && skip "remote OST with nodsh"
16106         remote_mds_nodsh && skip "remote MDS with nodsh"
16107
16108         local testdir=$DIR/$tdir/stats_testdir
16109
16110         test_mkdir -p $testdir
16111
16112         # verify obdfilter stats.
16113         $LFS setstripe -c 1 -i 0 $testdir/$tfile
16114         sync
16115         cancel_lru_locks osc
16116         wait_delete_completed
16117
16118         # clear stats.
16119         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16120         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16121
16122         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
16123                 error "dd failed"
16124         sync
16125         cancel_lru_locks osc
16126         check_stats ost1 "write" 1
16127
16128         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
16129         check_stats ost1 "read" 1
16130
16131         > $testdir/$tfile || error "truncate failed"
16132         check_stats ost1 "punch" 1
16133
16134         rm -f $testdir/$tfile || error "file remove failed"
16135         wait_delete_completed
16136         check_stats ost1 "destroy" 1
16137
16138         rm -rf $DIR/$tdir
16139 }
16140 run_test 133c "Verifying OST stats ========================================"
16141
16142 order_2() {
16143         local value=$1
16144         local orig=$value
16145         local order=1
16146
16147         while [ $value -ge 2 ]; do
16148                 order=$((order*2))
16149                 value=$((value/2))
16150         done
16151
16152         if [ $orig -gt $order ]; then
16153                 order=$((order*2))
16154         fi
16155         echo $order
16156 }
16157
16158 size_in_KMGT() {
16159     local value=$1
16160     local size=('K' 'M' 'G' 'T');
16161     local i=0
16162     local size_string=$value
16163
16164     while [ $value -ge 1024 ]; do
16165         if [ $i -gt 3 ]; then
16166             #T is the biggest unit we get here, if that is bigger,
16167             #just return XXXT
16168             size_string=${value}T
16169             break
16170         fi
16171         value=$((value >> 10))
16172         if [ $value -lt 1024 ]; then
16173             size_string=${value}${size[$i]}
16174             break
16175         fi
16176         i=$((i + 1))
16177     done
16178
16179     echo $size_string
16180 }
16181
16182 get_rename_size() {
16183         local size=$1
16184         local context=${2:-.}
16185         local sample=$(do_facet $SINGLEMDS $LCTL \
16186                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16187                 grep -A1 $context |
16188                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16189         echo $sample
16190 }
16191
16192 test_133d() {
16193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16194         remote_ost_nodsh && skip "remote OST with nodsh"
16195         remote_mds_nodsh && skip "remote MDS with nodsh"
16196         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16197                 skip_env "MDS doesn't support rename stats"
16198
16199         local testdir1=$DIR/${tdir}/stats_testdir1
16200         local testdir2=$DIR/${tdir}/stats_testdir2
16201         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16202
16203         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16204
16205         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16206         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16207
16208         createmany -o $testdir1/test 512 || error "createmany failed"
16209
16210         # check samedir rename size
16211         mv ${testdir1}/test0 ${testdir1}/test_0
16212
16213         local testdir1_size=$(ls -l $DIR/${tdir} |
16214                 awk '/stats_testdir1/ {print $5}')
16215         local testdir2_size=$(ls -l $DIR/${tdir} |
16216                 awk '/stats_testdir2/ {print $5}')
16217
16218         testdir1_size=$(order_2 $testdir1_size)
16219         testdir2_size=$(order_2 $testdir2_size)
16220
16221         testdir1_size=$(size_in_KMGT $testdir1_size)
16222         testdir2_size=$(size_in_KMGT $testdir2_size)
16223
16224         echo "source rename dir size: ${testdir1_size}"
16225         echo "target rename dir size: ${testdir2_size}"
16226
16227         local cmd="do_facet $SINGLEMDS $LCTL "
16228         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16229
16230         eval $cmd || error "$cmd failed"
16231         local samedir=$($cmd | grep 'same_dir')
16232         local same_sample=$(get_rename_size $testdir1_size)
16233         [ -z "$samedir" ] && error "samedir_rename_size count error"
16234         [[ $same_sample -eq 1 ]] ||
16235                 error "samedir_rename_size error $same_sample"
16236         echo "Check same dir rename stats success"
16237
16238         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16239
16240         # check crossdir rename size
16241         mv ${testdir1}/test_0 ${testdir2}/test_0
16242
16243         testdir1_size=$(ls -l $DIR/${tdir} |
16244                 awk '/stats_testdir1/ {print $5}')
16245         testdir2_size=$(ls -l $DIR/${tdir} |
16246                 awk '/stats_testdir2/ {print $5}')
16247
16248         testdir1_size=$(order_2 $testdir1_size)
16249         testdir2_size=$(order_2 $testdir2_size)
16250
16251         testdir1_size=$(size_in_KMGT $testdir1_size)
16252         testdir2_size=$(size_in_KMGT $testdir2_size)
16253
16254         echo "source rename dir size: ${testdir1_size}"
16255         echo "target rename dir size: ${testdir2_size}"
16256
16257         eval $cmd || error "$cmd failed"
16258         local crossdir=$($cmd | grep 'crossdir')
16259         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16260         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16261         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16262         [[ $src_sample -eq 1 ]] ||
16263                 error "crossdir_rename_size error $src_sample"
16264         [[ $tgt_sample -eq 1 ]] ||
16265                 error "crossdir_rename_size error $tgt_sample"
16266         echo "Check cross dir rename stats success"
16267         rm -rf $DIR/${tdir}
16268 }
16269 run_test 133d "Verifying rename_stats ========================================"
16270
16271 test_133e() {
16272         remote_mds_nodsh && skip "remote MDS with nodsh"
16273         remote_ost_nodsh && skip "remote OST with nodsh"
16274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16275
16276         local testdir=$DIR/${tdir}/stats_testdir
16277         local ctr f0 f1 bs=32768 count=42 sum
16278
16279         mkdir -p ${testdir} || error "mkdir failed"
16280
16281         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16282
16283         for ctr in {write,read}_bytes; do
16284                 sync
16285                 cancel_lru_locks osc
16286
16287                 do_facet ost1 $LCTL set_param -n \
16288                         "obdfilter.*.exports.clear=clear"
16289
16290                 if [ $ctr = write_bytes ]; then
16291                         f0=/dev/zero
16292                         f1=${testdir}/${tfile}
16293                 else
16294                         f0=${testdir}/${tfile}
16295                         f1=/dev/null
16296                 fi
16297
16298                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16299                         error "dd failed"
16300                 sync
16301                 cancel_lru_locks osc
16302
16303                 sum=$(do_facet ost1 $LCTL get_param \
16304                         "obdfilter.*.exports.*.stats" |
16305                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16306                                 $1 == ctr { sum += $7 }
16307                                 END { printf("%0.0f", sum) }')
16308
16309                 if ((sum != bs * count)); then
16310                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16311                 fi
16312         done
16313
16314         rm -rf $DIR/${tdir}
16315 }
16316 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16317
16318 test_133f() {
16319         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16320                 skip "too old lustre for get_param -R ($facet_ver)"
16321
16322         # verifying readability.
16323         $LCTL get_param -R '*' &> /dev/null
16324
16325         # Verifing writability with badarea_io.
16326         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16327         local skipped_params='force_lbug|changelog_mask|daemon_file'
16328         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16329                 egrep -v "$skipped_params" |
16330                 xargs -n 1 find $proc_dirs -name |
16331                 xargs -n 1 badarea_io ||
16332                 error "client badarea_io failed"
16333
16334         # remount the FS in case writes/reads /proc break the FS
16335         cleanup || error "failed to unmount"
16336         setup || error "failed to setup"
16337 }
16338 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16339
16340 test_133g() {
16341         remote_mds_nodsh && skip "remote MDS with nodsh"
16342         remote_ost_nodsh && skip "remote OST with nodsh"
16343
16344         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16345         local proc_dirs_str=$(eval echo $proc_dirs)
16346         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16347         local facet
16348         for facet in mds1 ost1; do
16349                 local facet_ver=$(lustre_version_code $facet)
16350                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16351                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16352                 else
16353                         log "$facet: too old lustre for get_param -R"
16354                 fi
16355                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16356                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16357                                 tr -d = | egrep -v $skipped_params |
16358                                 xargs -n 1 find $proc_dirs_str -name |
16359                                 xargs -n 1 badarea_io" ||
16360                                         error "$facet badarea_io failed"
16361                 else
16362                         skip_noexit "$facet: too old lustre for get_param -R"
16363                 fi
16364         done
16365
16366         # remount the FS in case writes/reads /proc break the FS
16367         cleanup || error "failed to unmount"
16368         setup || error "failed to setup"
16369 }
16370 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16371
16372 test_133h() {
16373         remote_mds_nodsh && skip "remote MDS with nodsh"
16374         remote_ost_nodsh && skip "remote OST with nodsh"
16375         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16376                 skip "Need MDS version at least 2.9.54"
16377
16378         local facet
16379         for facet in client mds1 ost1; do
16380                 # Get the list of files that are missing the terminating newline
16381                 local plist=$(do_facet $facet
16382                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16383                 local ent
16384                 for ent in $plist; do
16385                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16386                                 awk -v FS='\v' -v RS='\v\v' \
16387                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16388                                         print FILENAME}'" 2>/dev/null)
16389                         [ -z $missing ] || {
16390                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16391                                 error "file does not end with newline: $facet-$ent"
16392                         }
16393                 done
16394         done
16395 }
16396 run_test 133h "Proc files should end with newlines"
16397
16398 test_134a() {
16399         remote_mds_nodsh && skip "remote MDS with nodsh"
16400         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16401                 skip "Need MDS version at least 2.7.54"
16402
16403         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16404         cancel_lru_locks mdc
16405
16406         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16407         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16408         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16409
16410         local nr=1000
16411         createmany -o $DIR/$tdir/f $nr ||
16412                 error "failed to create $nr files in $DIR/$tdir"
16413         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16414
16415         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16416         do_facet mds1 $LCTL set_param fail_loc=0x327
16417         do_facet mds1 $LCTL set_param fail_val=500
16418         touch $DIR/$tdir/m
16419
16420         echo "sleep 10 seconds ..."
16421         sleep 10
16422         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16423
16424         do_facet mds1 $LCTL set_param fail_loc=0
16425         do_facet mds1 $LCTL set_param fail_val=0
16426         [ $lck_cnt -lt $unused ] ||
16427                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16428
16429         rm $DIR/$tdir/m
16430         unlinkmany $DIR/$tdir/f $nr
16431 }
16432 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16433
16434 test_134b() {
16435         remote_mds_nodsh && skip "remote MDS with nodsh"
16436         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16437                 skip "Need MDS version at least 2.7.54"
16438
16439         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16440         cancel_lru_locks mdc
16441
16442         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16443                         ldlm.lock_reclaim_threshold_mb)
16444         # disable reclaim temporarily
16445         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16446
16447         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16448         do_facet mds1 $LCTL set_param fail_loc=0x328
16449         do_facet mds1 $LCTL set_param fail_val=500
16450
16451         $LCTL set_param debug=+trace
16452
16453         local nr=600
16454         createmany -o $DIR/$tdir/f $nr &
16455         local create_pid=$!
16456
16457         echo "Sleep $TIMEOUT seconds ..."
16458         sleep $TIMEOUT
16459         if ! ps -p $create_pid  > /dev/null 2>&1; then
16460                 do_facet mds1 $LCTL set_param fail_loc=0
16461                 do_facet mds1 $LCTL set_param fail_val=0
16462                 do_facet mds1 $LCTL set_param \
16463                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16464                 error "createmany finished incorrectly!"
16465         fi
16466         do_facet mds1 $LCTL set_param fail_loc=0
16467         do_facet mds1 $LCTL set_param fail_val=0
16468         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16469         wait $create_pid || return 1
16470
16471         unlinkmany $DIR/$tdir/f $nr
16472 }
16473 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16474
16475 test_135() {
16476         remote_mds_nodsh && skip "remote MDS with nodsh"
16477         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16478                 skip "Need MDS version at least 2.13.50"
16479         local fname
16480
16481         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16482
16483 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16484         #set only one record at plain llog
16485         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16486
16487         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16488
16489         #fill already existed plain llog each 64767
16490         #wrapping whole catalog
16491         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16492
16493         createmany -o $DIR/$tdir/$tfile_ 64700
16494         for (( i = 0; i < 64700; i = i + 2 ))
16495         do
16496                 rm $DIR/$tdir/$tfile_$i &
16497                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16498                 local pid=$!
16499                 wait $pid
16500         done
16501
16502         #waiting osp synchronization
16503         wait_delete_completed
16504 }
16505 run_test 135 "Race catalog processing"
16506
16507 test_136() {
16508         remote_mds_nodsh && skip "remote MDS with nodsh"
16509         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16510                 skip "Need MDS version at least 2.13.50"
16511         local fname
16512
16513         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16514         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16515         #set only one record at plain llog
16516 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16517         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16518
16519         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16520
16521         #fill already existed 2 plain llogs each 64767
16522         #wrapping whole catalog
16523         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16524         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16525         wait_delete_completed
16526
16527         createmany -o $DIR/$tdir/$tfile_ 10
16528         sleep 25
16529
16530         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16531         for (( i = 0; i < 10; i = i + 3 ))
16532         do
16533                 rm $DIR/$tdir/$tfile_$i &
16534                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16535                 local pid=$!
16536                 wait $pid
16537                 sleep 7
16538                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16539         done
16540
16541         #waiting osp synchronization
16542         wait_delete_completed
16543 }
16544 run_test 136 "Race catalog processing 2"
16545
16546 test_140() { #bug-17379
16547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16548
16549         test_mkdir $DIR/$tdir
16550         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16551         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16552
16553         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16554         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16555         local i=0
16556         while i=$((i + 1)); do
16557                 test_mkdir $i
16558                 cd $i || error "Changing to $i"
16559                 ln -s ../stat stat || error "Creating stat symlink"
16560                 # Read the symlink until ELOOP present,
16561                 # not LBUGing the system is considered success,
16562                 # we didn't overrun the stack.
16563                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16564                 if [ $ret -ne 0 ]; then
16565                         if [ $ret -eq 40 ]; then
16566                                 break  # -ELOOP
16567                         else
16568                                 error "Open stat symlink"
16569                                         return
16570                         fi
16571                 fi
16572         done
16573         i=$((i - 1))
16574         echo "The symlink depth = $i"
16575         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16576                 error "Invalid symlink depth"
16577
16578         # Test recursive symlink
16579         ln -s symlink_self symlink_self
16580         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16581         echo "open symlink_self returns $ret"
16582         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16583 }
16584 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16585
16586 test_150a() {
16587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16588
16589         local TF="$TMP/$tfile"
16590
16591         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16592         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16593         cp $TF $DIR/$tfile
16594         cancel_lru_locks $OSC
16595         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16596         remount_client $MOUNT
16597         df -P $MOUNT
16598         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16599
16600         $TRUNCATE $TF 6000
16601         $TRUNCATE $DIR/$tfile 6000
16602         cancel_lru_locks $OSC
16603         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16604
16605         echo "12345" >>$TF
16606         echo "12345" >>$DIR/$tfile
16607         cancel_lru_locks $OSC
16608         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16609
16610         echo "12345" >>$TF
16611         echo "12345" >>$DIR/$tfile
16612         cancel_lru_locks $OSC
16613         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16614 }
16615 run_test 150a "truncate/append tests"
16616
16617 test_150b() {
16618         check_set_fallocate_or_skip
16619         local out
16620
16621         touch $DIR/$tfile
16622         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16623         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16624                 skip_eopnotsupp "$out|check_fallocate failed"
16625 }
16626 run_test 150b "Verify fallocate (prealloc) functionality"
16627
16628 test_150bb() {
16629         check_set_fallocate_or_skip
16630
16631         touch $DIR/$tfile
16632         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16633         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16634         > $DIR/$tfile
16635         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16636         # precomputed md5sum for 20MB of zeroes
16637         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16638         local sum=($(md5sum $DIR/$tfile))
16639
16640         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16641
16642         check_set_fallocate 1
16643
16644         > $DIR/$tfile
16645         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16646         sum=($(md5sum $DIR/$tfile))
16647
16648         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16649 }
16650 run_test 150bb "Verify fallocate modes both zero space"
16651
16652 test_150c() {
16653         check_set_fallocate_or_skip
16654         local striping="-c2"
16655
16656         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16657         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16658         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16659         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16660         local want=$((OSTCOUNT * 1048576))
16661
16662         # Must allocate all requested space, not more than 5% extra
16663         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16664                 error "bytes $bytes is not $want"
16665
16666         rm -f $DIR/$tfile
16667
16668         echo "verify fallocate on PFL file"
16669
16670         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16671
16672         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16673                 error "Create $DIR/$tfile failed"
16674         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16675         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16676         want=$((512 * 1048576))
16677
16678         # Must allocate all requested space, not more than 5% extra
16679         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16680                 error "bytes $bytes is not $want"
16681 }
16682 run_test 150c "Verify fallocate Size and Blocks"
16683
16684 test_150d() {
16685         check_set_fallocate_or_skip
16686         local striping="-c2"
16687
16688         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16689
16690         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16691         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16692                 error "setstripe failed"
16693         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16694         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16695         local want=$((OSTCOUNT * 1048576))
16696
16697         # Must allocate all requested space, not more than 5% extra
16698         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16699                 error "bytes $bytes is not $want"
16700 }
16701 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16702
16703 test_150e() {
16704         check_set_fallocate_or_skip
16705
16706         echo "df before:"
16707         $LFS df
16708         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16709         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16710                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16711
16712         # Find OST with Minimum Size
16713         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16714                        sort -un | head -1)
16715
16716         # Get 100MB per OST of the available space to reduce run time
16717         # else 60% of the available space if we are running SLOW tests
16718         if [ $SLOW == "no" ]; then
16719                 local space=$((1024 * 100 * OSTCOUNT))
16720         else
16721                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16722         fi
16723
16724         fallocate -l${space}k $DIR/$tfile ||
16725                 error "fallocate ${space}k $DIR/$tfile failed"
16726         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16727
16728         # get size immediately after fallocate. This should be correctly
16729         # updated
16730         local size=$(stat -c '%s' $DIR/$tfile)
16731         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16732
16733         # Sleep for a while for statfs to get updated. And not pull from cache.
16734         sleep 2
16735
16736         echo "df after fallocate:"
16737         $LFS df
16738
16739         (( size / 1024 == space )) || error "size $size != requested $space"
16740         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16741                 error "used $used < space $space"
16742
16743         rm $DIR/$tfile || error "rm failed"
16744         sync
16745         wait_delete_completed
16746
16747         echo "df after unlink:"
16748         $LFS df
16749 }
16750 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16751
16752 test_150f() {
16753         local size
16754         local blocks
16755         local want_size_before=20480 # in bytes
16756         local want_blocks_before=40 # 512 sized blocks
16757         local want_blocks_after=24  # 512 sized blocks
16758         local length=$(((want_blocks_before - want_blocks_after) * 512))
16759
16760         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16761                 skip "need at least 2.14.0 for fallocate punch"
16762
16763         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16764                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16765         fi
16766
16767         check_set_fallocate_or_skip
16768         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16769
16770         [[ "x$DOM" == "xyes" ]] &&
16771                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16772
16773         echo "Verify fallocate punch: Range within the file range"
16774         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16775                 error "dd failed for bs 4096 and count 5"
16776
16777         # Call fallocate with punch range which is within the file range
16778         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16779                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16780         # client must see changes immediately after fallocate
16781         size=$(stat -c '%s' $DIR/$tfile)
16782         blocks=$(stat -c '%b' $DIR/$tfile)
16783
16784         # Verify punch worked.
16785         (( blocks == want_blocks_after )) ||
16786                 error "punch failed: blocks $blocks != $want_blocks_after"
16787
16788         (( size == want_size_before )) ||
16789                 error "punch failed: size $size != $want_size_before"
16790
16791         # Verify there is hole in file
16792         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16793         # precomputed md5sum
16794         local expect="4a9a834a2db02452929c0a348273b4aa"
16795
16796         cksum=($(md5sum $DIR/$tfile))
16797         [[ "${cksum[0]}" == "$expect" ]] ||
16798                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16799
16800         # Start second sub-case for fallocate punch.
16801         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16802         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16803                 error "dd failed for bs 4096 and count 5"
16804
16805         # Punch range less than block size will have no change in block count
16806         want_blocks_after=40  # 512 sized blocks
16807
16808         # Punch overlaps two blocks and less than blocksize
16809         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16810                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16811         size=$(stat -c '%s' $DIR/$tfile)
16812         blocks=$(stat -c '%b' $DIR/$tfile)
16813
16814         # Verify punch worked.
16815         (( blocks == want_blocks_after )) ||
16816                 error "punch failed: blocks $blocks != $want_blocks_after"
16817
16818         (( size == want_size_before )) ||
16819                 error "punch failed: size $size != $want_size_before"
16820
16821         # Verify if range is really zero'ed out. We expect Zeros.
16822         # precomputed md5sum
16823         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16824         cksum=($(md5sum $DIR/$tfile))
16825         [[ "${cksum[0]}" == "$expect" ]] ||
16826                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16827 }
16828 run_test 150f "Verify fallocate punch functionality"
16829
16830 test_150g() {
16831         local space
16832         local size
16833         local blocks
16834         local blocks_after
16835         local size_after
16836         local BS=4096 # Block size in bytes
16837
16838         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16839                 skip "need at least 2.14.0 for fallocate punch"
16840
16841         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16842                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16843         fi
16844
16845         check_set_fallocate_or_skip
16846         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16847
16848         if [[ "x$DOM" == "xyes" ]]; then
16849                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16850                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16851         else
16852                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16853                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16854         fi
16855
16856         # Get 100MB per OST of the available space to reduce run time
16857         # else 60% of the available space if we are running SLOW tests
16858         if [ $SLOW == "no" ]; then
16859                 space=$((1024 * 100 * OSTCOUNT))
16860         else
16861                 # Find OST with Minimum Size
16862                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16863                         sort -un | head -1)
16864                 echo "min size OST: $space"
16865                 space=$(((space * 60)/100 * OSTCOUNT))
16866         fi
16867         # space in 1k units, round to 4k blocks
16868         local blkcount=$((space * 1024 / $BS))
16869
16870         echo "Verify fallocate punch: Very large Range"
16871         fallocate -l${space}k $DIR/$tfile ||
16872                 error "fallocate ${space}k $DIR/$tfile failed"
16873         # write 1M at the end, start and in the middle
16874         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16875                 error "dd failed: bs $BS count 256"
16876         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16877                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16878         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16879                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16880
16881         # Gather stats.
16882         size=$(stat -c '%s' $DIR/$tfile)
16883
16884         # gather punch length.
16885         local punch_size=$((size - (BS * 2)))
16886
16887         echo "punch_size = $punch_size"
16888         echo "size - punch_size: $((size - punch_size))"
16889         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16890
16891         # Call fallocate to punch all except 2 blocks. We leave the
16892         # first and the last block
16893         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16894         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16895                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16896
16897         size_after=$(stat -c '%s' $DIR/$tfile)
16898         blocks_after=$(stat -c '%b' $DIR/$tfile)
16899
16900         # Verify punch worked.
16901         # Size should be kept
16902         (( size == size_after )) ||
16903                 error "punch failed: size $size != $size_after"
16904
16905         # two 4k data blocks to remain plus possible 1 extra extent block
16906         (( blocks_after <= ((BS / 512) * 3) )) ||
16907                 error "too many blocks remains: $blocks_after"
16908
16909         # Verify that file has hole between the first and the last blocks
16910         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16911         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16912
16913         echo "Hole at [$hole_start, $hole_end)"
16914         (( hole_start == BS )) ||
16915                 error "no hole at offset $BS after punch"
16916
16917         (( hole_end == BS + punch_size )) ||
16918                 error "data at offset $hole_end < $((BS + punch_size))"
16919 }
16920 run_test 150g "Verify fallocate punch on large range"
16921
16922 test_150h() {
16923         local file=$DIR/$tfile
16924         local size
16925
16926         check_set_fallocate_or_skip
16927         statx_supported || skip_env "Test must be statx() syscall supported"
16928
16929         # fallocate() does not update the size information on the MDT
16930         fallocate -l 16K $file || error "failed to fallocate $file"
16931         cancel_lru_locks $OSC
16932         # STATX with cached-always mode will not send glimpse RPCs to OST,
16933         # it uses the caching attrs on the client side as much as possible.
16934         size=$($STATX --cached=always -c %s $file)
16935         [ $size == 16384 ] ||
16936                 error "size after fallocate() is $size, expected 16384"
16937 }
16938 run_test 150h "Verify extend fallocate updates the file size"
16939
16940 #LU-2902 roc_hit was not able to read all values from lproc
16941 function roc_hit_init() {
16942         local list=$(comma_list $(osts_nodes))
16943         local dir=$DIR/$tdir-check
16944         local file=$dir/$tfile
16945         local BEFORE
16946         local AFTER
16947         local idx
16948
16949         test_mkdir $dir
16950         #use setstripe to do a write to every ost
16951         for i in $(seq 0 $((OSTCOUNT-1))); do
16952                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16953                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16954                 idx=$(printf %04x $i)
16955                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16956                         awk '$1 == "cache_access" {sum += $7}
16957                                 END { printf("%0.0f", sum) }')
16958
16959                 cancel_lru_locks osc
16960                 cat $file >/dev/null
16961
16962                 AFTER=$(get_osd_param $list *OST*$idx stats |
16963                         awk '$1 == "cache_access" {sum += $7}
16964                                 END { printf("%0.0f", sum) }')
16965
16966                 echo BEFORE:$BEFORE AFTER:$AFTER
16967                 if ! let "AFTER - BEFORE == 4"; then
16968                         rm -rf $dir
16969                         error "roc_hit is not safe to use"
16970                 fi
16971                 rm $file
16972         done
16973
16974         rm -rf $dir
16975 }
16976
16977 function roc_hit() {
16978         local list=$(comma_list $(osts_nodes))
16979         echo $(get_osd_param $list '' stats |
16980                 awk '$1 == "cache_hit" {sum += $7}
16981                         END { printf("%0.0f", sum) }')
16982 }
16983
16984 function set_cache() {
16985         local on=1
16986
16987         if [ "$2" == "off" ]; then
16988                 on=0;
16989         fi
16990         local list=$(comma_list $(osts_nodes))
16991         set_osd_param $list '' $1_cache_enable $on
16992
16993         cancel_lru_locks osc
16994 }
16995
16996 test_151() {
16997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16998         remote_ost_nodsh && skip "remote OST with nodsh"
16999         (( CLIENT_VERSION == OST1_VERSION )) ||
17000                 skip "LU-13081: no interop testing for OSS cache"
17001
17002         local CPAGES=3
17003         local list=$(comma_list $(osts_nodes))
17004
17005         # check whether obdfilter is cache capable at all
17006         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
17007                 skip "not cache-capable obdfilter"
17008         fi
17009
17010         # check cache is enabled on all obdfilters
17011         if get_osd_param $list '' read_cache_enable | grep 0; then
17012                 skip "oss cache is disabled"
17013         fi
17014
17015         set_osd_param $list '' writethrough_cache_enable 1
17016
17017         # check write cache is enabled on all obdfilters
17018         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
17019                 skip "oss write cache is NOT enabled"
17020         fi
17021
17022         roc_hit_init
17023
17024         #define OBD_FAIL_OBD_NO_LRU  0x609
17025         do_nodes $list $LCTL set_param fail_loc=0x609
17026
17027         # pages should be in the case right after write
17028         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
17029                 error "dd failed"
17030
17031         local BEFORE=$(roc_hit)
17032         cancel_lru_locks osc
17033         cat $DIR/$tfile >/dev/null
17034         local AFTER=$(roc_hit)
17035
17036         do_nodes $list $LCTL set_param fail_loc=0
17037
17038         if ! let "AFTER - BEFORE == CPAGES"; then
17039                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
17040         fi
17041
17042         cancel_lru_locks osc
17043         # invalidates OST cache
17044         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
17045         set_osd_param $list '' read_cache_enable 0
17046         cat $DIR/$tfile >/dev/null
17047
17048         # now data shouldn't be found in the cache
17049         BEFORE=$(roc_hit)
17050         cancel_lru_locks osc
17051         cat $DIR/$tfile >/dev/null
17052         AFTER=$(roc_hit)
17053         if let "AFTER - BEFORE != 0"; then
17054                 error "IN CACHE: before: $BEFORE, after: $AFTER"
17055         fi
17056
17057         set_osd_param $list '' read_cache_enable 1
17058         rm -f $DIR/$tfile
17059 }
17060 run_test 151 "test cache on oss and controls ==============================="
17061
17062 test_152() {
17063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17064
17065         local TF="$TMP/$tfile"
17066
17067         # simulate ENOMEM during write
17068 #define OBD_FAIL_OST_NOMEM      0x226
17069         lctl set_param fail_loc=0x80000226
17070         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
17071         cp $TF $DIR/$tfile
17072         sync || error "sync failed"
17073         lctl set_param fail_loc=0
17074
17075         # discard client's cache
17076         cancel_lru_locks osc
17077
17078         # simulate ENOMEM during read
17079         lctl set_param fail_loc=0x80000226
17080         cmp $TF $DIR/$tfile || error "cmp failed"
17081         lctl set_param fail_loc=0
17082
17083         rm -f $TF
17084 }
17085 run_test 152 "test read/write with enomem ============================"
17086
17087 test_153() {
17088         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
17089 }
17090 run_test 153 "test if fdatasync does not crash ======================="
17091
17092 dot_lustre_fid_permission_check() {
17093         local fid=$1
17094         local ffid=$MOUNT/.lustre/fid/$fid
17095         local test_dir=$2
17096
17097         echo "stat fid $fid"
17098         stat $ffid || error "stat $ffid failed."
17099         echo "touch fid $fid"
17100         touch $ffid || error "touch $ffid failed."
17101         echo "write to fid $fid"
17102         cat /etc/hosts > $ffid || error "write $ffid failed."
17103         echo "read fid $fid"
17104         diff /etc/hosts $ffid || error "read $ffid failed."
17105         echo "append write to fid $fid"
17106         cat /etc/hosts >> $ffid || error "append write $ffid failed."
17107         echo "rename fid $fid"
17108         mv $ffid $test_dir/$tfile.1 &&
17109                 error "rename $ffid to $tfile.1 should fail."
17110         touch $test_dir/$tfile.1
17111         mv $test_dir/$tfile.1 $ffid &&
17112                 error "rename $tfile.1 to $ffid should fail."
17113         rm -f $test_dir/$tfile.1
17114         echo "truncate fid $fid"
17115         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
17116         echo "link fid $fid"
17117         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
17118         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
17119                 id $USER0 || skip_env "missing user $USER0"
17120                 echo "setfacl fid $fid"
17121                 setfacl -R -m u:$USER0:rwx $ffid ||
17122                         error "setfacl $ffid failed"
17123                 echo "getfacl fid $fid"
17124                 getfacl $ffid || error "getfacl $ffid failed."
17125         fi
17126         echo "unlink fid $fid"
17127         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
17128         echo "mknod fid $fid"
17129         mknod $ffid c 1 3 && error "mknod $ffid should fail."
17130
17131         fid=[0xf00000400:0x1:0x0]
17132         ffid=$MOUNT/.lustre/fid/$fid
17133
17134         echo "stat non-exist fid $fid"
17135         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
17136         echo "write to non-exist fid $fid"
17137         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
17138         echo "link new fid $fid"
17139         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
17140
17141         mkdir -p $test_dir/$tdir
17142         touch $test_dir/$tdir/$tfile
17143         fid=$($LFS path2fid $test_dir/$tdir)
17144         rc=$?
17145         [ $rc -ne 0 ] &&
17146                 error "error: could not get fid for $test_dir/$dir/$tfile."
17147
17148         ffid=$MOUNT/.lustre/fid/$fid
17149
17150         echo "ls $fid"
17151         ls $ffid || error "ls $ffid failed."
17152         echo "touch $fid/$tfile.1"
17153         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17154
17155         echo "touch $MOUNT/.lustre/fid/$tfile"
17156         touch $MOUNT/.lustre/fid/$tfile && \
17157                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17158
17159         echo "setxattr to $MOUNT/.lustre/fid"
17160         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17161
17162         echo "listxattr for $MOUNT/.lustre/fid"
17163         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17164
17165         echo "delxattr from $MOUNT/.lustre/fid"
17166         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17167
17168         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17169         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17170                 error "touch invalid fid should fail."
17171
17172         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17173         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17174                 error "touch non-normal fid should fail."
17175
17176         echo "rename $tdir to $MOUNT/.lustre/fid"
17177         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17178                 error "rename to $MOUNT/.lustre/fid should fail."
17179
17180         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17181         then            # LU-3547
17182                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17183                 local new_obf_mode=777
17184
17185                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17186                 chmod $new_obf_mode $DIR/.lustre/fid ||
17187                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17188
17189                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17190                 [ $obf_mode -eq $new_obf_mode ] ||
17191                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17192
17193                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17194                 chmod $old_obf_mode $DIR/.lustre/fid ||
17195                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17196         fi
17197
17198         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17199         fid=$($LFS path2fid $test_dir/$tfile-2)
17200
17201         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17202         then # LU-5424
17203                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17204                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17205                         error "create lov data thru .lustre failed"
17206         fi
17207         echo "cp /etc/passwd $test_dir/$tfile-2"
17208         cp /etc/passwd $test_dir/$tfile-2 ||
17209                 error "copy to $test_dir/$tfile-2 failed."
17210         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17211         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17212                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17213
17214         rm -rf $test_dir/tfile.lnk
17215         rm -rf $test_dir/$tfile-2
17216 }
17217
17218 test_154A() {
17219         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17220                 skip "Need MDS version at least 2.4.1"
17221
17222         local tf=$DIR/$tfile
17223         touch $tf
17224
17225         local fid=$($LFS path2fid $tf)
17226         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17227
17228         # check that we get the same pathname back
17229         local rootpath
17230         local found
17231         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17232                 echo "$rootpath $fid"
17233                 found=$($LFS fid2path $rootpath "$fid")
17234                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17235                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17236         done
17237
17238         # check wrong root path format
17239         rootpath=$MOUNT"_wrong"
17240         found=$($LFS fid2path $rootpath "$fid")
17241         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17242 }
17243 run_test 154A "lfs path2fid and fid2path basic checks"
17244
17245 test_154B() {
17246         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17247                 skip "Need MDS version at least 2.4.1"
17248
17249         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17250         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17251         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17252         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17253
17254         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17255         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17256
17257         # check that we get the same pathname
17258         echo "PFID: $PFID, name: $name"
17259         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17260         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17261         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17262                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17263
17264         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17265 }
17266 run_test 154B "verify the ll_decode_linkea tool"
17267
17268 test_154a() {
17269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17270         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17271         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17272                 skip "Need MDS version at least 2.2.51"
17273         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17274
17275         cp /etc/hosts $DIR/$tfile
17276
17277         fid=$($LFS path2fid $DIR/$tfile)
17278         rc=$?
17279         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17280
17281         dot_lustre_fid_permission_check "$fid" $DIR ||
17282                 error "dot lustre permission check $fid failed"
17283
17284         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17285
17286         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17287
17288         touch $MOUNT/.lustre/file &&
17289                 error "creation is not allowed under .lustre"
17290
17291         mkdir $MOUNT/.lustre/dir &&
17292                 error "mkdir is not allowed under .lustre"
17293
17294         rm -rf $DIR/$tfile
17295 }
17296 run_test 154a "Open-by-FID"
17297
17298 test_154b() {
17299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17300         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17302         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17303                 skip "Need MDS version at least 2.2.51"
17304
17305         local remote_dir=$DIR/$tdir/remote_dir
17306         local MDTIDX=1
17307         local rc=0
17308
17309         mkdir -p $DIR/$tdir
17310         $LFS mkdir -i $MDTIDX $remote_dir ||
17311                 error "create remote directory failed"
17312
17313         cp /etc/hosts $remote_dir/$tfile
17314
17315         fid=$($LFS path2fid $remote_dir/$tfile)
17316         rc=$?
17317         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17318
17319         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17320                 error "dot lustre permission check $fid failed"
17321         rm -rf $DIR/$tdir
17322 }
17323 run_test 154b "Open-by-FID for remote directory"
17324
17325 test_154c() {
17326         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17327                 skip "Need MDS version at least 2.4.1"
17328
17329         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17330         local FID1=$($LFS path2fid $DIR/$tfile.1)
17331         local FID2=$($LFS path2fid $DIR/$tfile.2)
17332         local FID3=$($LFS path2fid $DIR/$tfile.3)
17333
17334         local N=1
17335         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17336                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17337                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17338                 local want=FID$N
17339                 [ "$FID" = "${!want}" ] ||
17340                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17341                 N=$((N + 1))
17342         done
17343
17344         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17345         do
17346                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17347                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17348                 N=$((N + 1))
17349         done
17350 }
17351 run_test 154c "lfs path2fid and fid2path multiple arguments"
17352
17353 test_154d() {
17354         remote_mds_nodsh && skip "remote MDS with nodsh"
17355         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17356                 skip "Need MDS version at least 2.5.53"
17357
17358         if remote_mds; then
17359                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17360         else
17361                 nid="0@lo"
17362         fi
17363         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17364         local fd
17365         local cmd
17366
17367         rm -f $DIR/$tfile
17368         touch $DIR/$tfile
17369
17370         local fid=$($LFS path2fid $DIR/$tfile)
17371         # Open the file
17372         fd=$(free_fd)
17373         cmd="exec $fd<$DIR/$tfile"
17374         eval $cmd
17375         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17376         echo "$fid_list" | grep "$fid"
17377         rc=$?
17378
17379         cmd="exec $fd>/dev/null"
17380         eval $cmd
17381         if [ $rc -ne 0 ]; then
17382                 error "FID $fid not found in open files list $fid_list"
17383         fi
17384 }
17385 run_test 154d "Verify open file fid"
17386
17387 test_154e()
17388 {
17389         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17390                 skip "Need MDS version at least 2.6.50"
17391
17392         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17393                 error ".lustre returned by readdir"
17394         fi
17395 }
17396 run_test 154e ".lustre is not returned by readdir"
17397
17398 test_154f() {
17399         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17400
17401         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17402         mkdir_on_mdt0 $DIR/$tdir
17403         # test dirs inherit from its stripe
17404         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17405         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17406         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17407         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17408         touch $DIR/f
17409
17410         # get fid of parents
17411         local FID0=$($LFS path2fid $DIR/$tdir)
17412         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17413         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17414         local FID3=$($LFS path2fid $DIR)
17415
17416         # check that path2fid --parents returns expected <parent_fid>/name
17417         # 1) test for a directory (single parent)
17418         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17419         [ "$parent" == "$FID0/foo1" ] ||
17420                 error "expected parent: $FID0/foo1, got: $parent"
17421
17422         # 2) test for a file with nlink > 1 (multiple parents)
17423         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17424         echo "$parent" | grep -F "$FID1/$tfile" ||
17425                 error "$FID1/$tfile not returned in parent list"
17426         echo "$parent" | grep -F "$FID2/link" ||
17427                 error "$FID2/link not returned in parent list"
17428
17429         # 3) get parent by fid
17430         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17431         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17432         echo "$parent" | grep -F "$FID1/$tfile" ||
17433                 error "$FID1/$tfile not returned in parent list (by fid)"
17434         echo "$parent" | grep -F "$FID2/link" ||
17435                 error "$FID2/link not returned in parent list (by fid)"
17436
17437         # 4) test for entry in root directory
17438         parent=$($LFS path2fid --parents $DIR/f)
17439         echo "$parent" | grep -F "$FID3/f" ||
17440                 error "$FID3/f not returned in parent list"
17441
17442         # 5) test it on root directory
17443         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17444                 error "$MOUNT should not have parents"
17445
17446         # enable xattr caching and check that linkea is correctly updated
17447         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17448         save_lustre_params client "llite.*.xattr_cache" > $save
17449         lctl set_param llite.*.xattr_cache 1
17450
17451         # 6.1) linkea update on rename
17452         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17453
17454         # get parents by fid
17455         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17456         # foo1 should no longer be returned in parent list
17457         echo "$parent" | grep -F "$FID1" &&
17458                 error "$FID1 should no longer be in parent list"
17459         # the new path should appear
17460         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17461                 error "$FID2/$tfile.moved is not in parent list"
17462
17463         # 6.2) linkea update on unlink
17464         rm -f $DIR/$tdir/foo2/link
17465         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17466         # foo2/link should no longer be returned in parent list
17467         echo "$parent" | grep -F "$FID2/link" &&
17468                 error "$FID2/link should no longer be in parent list"
17469         true
17470
17471         rm -f $DIR/f
17472         restore_lustre_params < $save
17473         rm -f $save
17474 }
17475 run_test 154f "get parent fids by reading link ea"
17476
17477 test_154g()
17478 {
17479         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17480            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17481                 skip "Need MDS version at least 2.6.92"
17482
17483         mkdir_on_mdt0 $DIR/$tdir
17484         llapi_fid_test -d $DIR/$tdir
17485 }
17486 run_test 154g "various llapi FID tests"
17487
17488 test_154h()
17489 {
17490         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17491                 skip "Need client at least version 2.15.55.1"
17492
17493         # Create an empty file
17494         touch $DIR/$tfile
17495
17496         # Get FID (interactive mode) and save under $TMP/$tfile.log
17497         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17498                 path2fid $DIR/$tfile
17499         EOF
17500
17501         fid=$(cat $TMP/$tfile.log)
17502         # $fid should not be empty
17503         [[ ! -z $fid ]] || error "FID is empty"
17504         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17505 }
17506 run_test 154h "Verify interactive path2fid"
17507
17508 test_155_small_load() {
17509     local temp=$TMP/$tfile
17510     local file=$DIR/$tfile
17511
17512     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17513         error "dd of=$temp bs=6096 count=1 failed"
17514     cp $temp $file
17515     cancel_lru_locks $OSC
17516     cmp $temp $file || error "$temp $file differ"
17517
17518     $TRUNCATE $temp 6000
17519     $TRUNCATE $file 6000
17520     cmp $temp $file || error "$temp $file differ (truncate1)"
17521
17522     echo "12345" >>$temp
17523     echo "12345" >>$file
17524     cmp $temp $file || error "$temp $file differ (append1)"
17525
17526     echo "12345" >>$temp
17527     echo "12345" >>$file
17528     cmp $temp $file || error "$temp $file differ (append2)"
17529
17530     rm -f $temp $file
17531     true
17532 }
17533
17534 test_155_big_load() {
17535         remote_ost_nodsh && skip "remote OST with nodsh"
17536
17537         local temp=$TMP/$tfile
17538         local file=$DIR/$tfile
17539
17540         free_min_max
17541         local cache_size=$(do_facet ost$((MAXI+1)) \
17542                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17543
17544         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17545         # pre-set value
17546         if [ -z "$cache_size" ]; then
17547                 cache_size=256
17548         fi
17549         local large_file_size=$((cache_size * 2))
17550
17551         echo "OSS cache size: $cache_size KB"
17552         echo "Large file size: $large_file_size KB"
17553
17554         [ $MAXV -le $large_file_size ] &&
17555                 skip_env "max available OST size needs > $large_file_size KB"
17556
17557         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17558
17559         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17560                 error "dd of=$temp bs=$large_file_size count=1k failed"
17561         cp $temp $file
17562         ls -lh $temp $file
17563         cancel_lru_locks osc
17564         cmp $temp $file || error "$temp $file differ"
17565
17566         rm -f $temp $file
17567         true
17568 }
17569
17570 save_writethrough() {
17571         local facets=$(get_facets OST)
17572
17573         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17574 }
17575
17576 test_155a() {
17577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17578
17579         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17580
17581         save_writethrough $p
17582
17583         set_cache read on
17584         set_cache writethrough on
17585         test_155_small_load
17586         restore_lustre_params < $p
17587         rm -f $p
17588 }
17589 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17590
17591 test_155b() {
17592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17593
17594         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17595
17596         save_writethrough $p
17597
17598         set_cache read on
17599         set_cache writethrough off
17600         test_155_small_load
17601         restore_lustre_params < $p
17602         rm -f $p
17603 }
17604 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17605
17606 test_155c() {
17607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17608
17609         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17610
17611         save_writethrough $p
17612
17613         set_cache read off
17614         set_cache writethrough on
17615         test_155_small_load
17616         restore_lustre_params < $p
17617         rm -f $p
17618 }
17619 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17620
17621 test_155d() {
17622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17623
17624         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17625
17626         save_writethrough $p
17627
17628         set_cache read off
17629         set_cache writethrough off
17630         test_155_small_load
17631         restore_lustre_params < $p
17632         rm -f $p
17633 }
17634 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17635
17636 test_155e() {
17637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17638
17639         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17640
17641         save_writethrough $p
17642
17643         set_cache read on
17644         set_cache writethrough on
17645         test_155_big_load
17646         restore_lustre_params < $p
17647         rm -f $p
17648 }
17649 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17650
17651 test_155f() {
17652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17653
17654         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17655
17656         save_writethrough $p
17657
17658         set_cache read on
17659         set_cache writethrough off
17660         test_155_big_load
17661         restore_lustre_params < $p
17662         rm -f $p
17663 }
17664 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17665
17666 test_155g() {
17667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17668
17669         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17670
17671         save_writethrough $p
17672
17673         set_cache read off
17674         set_cache writethrough on
17675         test_155_big_load
17676         restore_lustre_params < $p
17677         rm -f $p
17678 }
17679 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17680
17681 test_155h() {
17682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17683
17684         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17685
17686         save_writethrough $p
17687
17688         set_cache read off
17689         set_cache writethrough off
17690         test_155_big_load
17691         restore_lustre_params < $p
17692         rm -f $p
17693 }
17694 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17695
17696 test_156() {
17697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17698         remote_ost_nodsh && skip "remote OST with nodsh"
17699         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17700                 skip "stats not implemented on old servers"
17701         [ "$ost1_FSTYPE" = "zfs" ] &&
17702                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17703         (( CLIENT_VERSION == OST1_VERSION )) ||
17704                 skip "LU-13081: no interop testing for OSS cache"
17705
17706         local CPAGES=3
17707         local BEFORE
17708         local AFTER
17709         local file="$DIR/$tfile"
17710         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17711
17712         save_writethrough $p
17713         roc_hit_init
17714
17715         log "Turn on read and write cache"
17716         set_cache read on
17717         set_cache writethrough on
17718
17719         log "Write data and read it back."
17720         log "Read should be satisfied from the cache."
17721         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17722         BEFORE=$(roc_hit)
17723         cancel_lru_locks osc
17724         cat $file >/dev/null
17725         AFTER=$(roc_hit)
17726         if ! let "AFTER - BEFORE == CPAGES"; then
17727                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17728         else
17729                 log "cache hits: before: $BEFORE, after: $AFTER"
17730         fi
17731
17732         log "Read again; it should be satisfied from the cache."
17733         BEFORE=$AFTER
17734         cancel_lru_locks osc
17735         cat $file >/dev/null
17736         AFTER=$(roc_hit)
17737         if ! let "AFTER - BEFORE == CPAGES"; then
17738                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17739         else
17740                 log "cache hits:: before: $BEFORE, after: $AFTER"
17741         fi
17742
17743         log "Turn off the read cache and turn on the write cache"
17744         set_cache read off
17745         set_cache writethrough on
17746
17747         log "Read again; it should be satisfied from the cache."
17748         BEFORE=$(roc_hit)
17749         cancel_lru_locks osc
17750         cat $file >/dev/null
17751         AFTER=$(roc_hit)
17752         if ! let "AFTER - BEFORE == CPAGES"; then
17753                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17754         else
17755                 log "cache hits:: before: $BEFORE, after: $AFTER"
17756         fi
17757
17758         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17759                 # > 2.12.56 uses pagecache if cached
17760                 log "Read again; it should not be satisfied from the cache."
17761                 BEFORE=$AFTER
17762                 cancel_lru_locks osc
17763                 cat $file >/dev/null
17764                 AFTER=$(roc_hit)
17765                 if ! let "AFTER - BEFORE == 0"; then
17766                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17767                 else
17768                         log "cache hits:: before: $BEFORE, after: $AFTER"
17769                 fi
17770         fi
17771
17772         log "Write data and read it back."
17773         log "Read should be satisfied from the cache."
17774         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17775         BEFORE=$(roc_hit)
17776         cancel_lru_locks osc
17777         cat $file >/dev/null
17778         AFTER=$(roc_hit)
17779         if ! let "AFTER - BEFORE == CPAGES"; then
17780                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17781         else
17782                 log "cache hits:: before: $BEFORE, after: $AFTER"
17783         fi
17784
17785         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17786                 # > 2.12.56 uses pagecache if cached
17787                 log "Read again; it should not be satisfied from the cache."
17788                 BEFORE=$AFTER
17789                 cancel_lru_locks osc
17790                 cat $file >/dev/null
17791                 AFTER=$(roc_hit)
17792                 if ! let "AFTER - BEFORE == 0"; then
17793                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17794                 else
17795                         log "cache hits:: before: $BEFORE, after: $AFTER"
17796                 fi
17797         fi
17798
17799         log "Turn off read and write cache"
17800         set_cache read off
17801         set_cache writethrough off
17802
17803         log "Write data and read it back"
17804         log "It should not be satisfied from the cache."
17805         rm -f $file
17806         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17807         cancel_lru_locks osc
17808         BEFORE=$(roc_hit)
17809         cat $file >/dev/null
17810         AFTER=$(roc_hit)
17811         if ! let "AFTER - BEFORE == 0"; then
17812                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17813         else
17814                 log "cache hits:: before: $BEFORE, after: $AFTER"
17815         fi
17816
17817         log "Turn on the read cache and turn off the write cache"
17818         set_cache read on
17819         set_cache writethrough off
17820
17821         log "Write data and read it back"
17822         log "It should not be satisfied from the cache."
17823         rm -f $file
17824         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17825         BEFORE=$(roc_hit)
17826         cancel_lru_locks osc
17827         cat $file >/dev/null
17828         AFTER=$(roc_hit)
17829         if ! let "AFTER - BEFORE == 0"; then
17830                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17831         else
17832                 log "cache hits:: before: $BEFORE, after: $AFTER"
17833         fi
17834
17835         log "Read again; it should be satisfied from the cache."
17836         BEFORE=$(roc_hit)
17837         cancel_lru_locks osc
17838         cat $file >/dev/null
17839         AFTER=$(roc_hit)
17840         if ! let "AFTER - BEFORE == CPAGES"; then
17841                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17842         else
17843                 log "cache hits:: before: $BEFORE, after: $AFTER"
17844         fi
17845
17846         restore_lustre_params < $p
17847         rm -f $p $file
17848 }
17849 run_test 156 "Verification of tunables"
17850
17851 test_160a() {
17852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17853         remote_mds_nodsh && skip "remote MDS with nodsh"
17854         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17855                 skip "Need MDS version at least 2.2.0"
17856
17857         changelog_register || error "changelog_register failed"
17858         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17859         changelog_users $SINGLEMDS | grep -q $cl_user ||
17860                 error "User $cl_user not found in changelog_users"
17861
17862         mkdir_on_mdt0 $DIR/$tdir
17863
17864         # change something
17865         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17866         changelog_clear 0 || error "changelog_clear failed"
17867         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17868         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17869         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17870         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17871         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17872         rm $DIR/$tdir/pics/desktop.jpg
17873
17874         echo "verifying changelog mask"
17875         changelog_chmask "-MKDIR"
17876         changelog_chmask "-CLOSE"
17877
17878         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17879         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17880
17881         changelog_chmask "+MKDIR"
17882         changelog_chmask "+CLOSE"
17883
17884         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17885         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17886
17887         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17888         CLOSES=$(changelog_dump | grep -c "CLOSE")
17889         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17890         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17891
17892         # verify contents
17893         echo "verifying target fid"
17894         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17895         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17896         [ "$fidc" == "$fidf" ] ||
17897                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17898         echo "verifying parent fid"
17899         # The FID returned from the Changelog may be the directory shard on
17900         # a different MDT, and not the FID returned by path2fid on the parent.
17901         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17902         # since this is what will matter when recreating this file in the tree.
17903         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17904         local pathp=$($LFS fid2path $MOUNT "$fidp")
17905         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17906                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17907
17908         echo "getting records for $cl_user"
17909         changelog_users $SINGLEMDS
17910         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17911         local nclr=3
17912         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17913                 error "changelog_clear failed"
17914         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17915         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17916         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17917                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17918
17919         local min0_rec=$(changelog_users $SINGLEMDS |
17920                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17921         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17922                           awk '{ print $1; exit; }')
17923
17924         changelog_dump | tail -n 5
17925         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17926         [ $first_rec == $((min0_rec + 1)) ] ||
17927                 error "first index should be $min0_rec + 1 not $first_rec"
17928
17929         # LU-3446 changelog index reset on MDT restart
17930         local cur_rec1=$(changelog_users $SINGLEMDS |
17931                          awk '/^current.index:/ { print $NF }')
17932         changelog_clear 0 ||
17933                 error "clear all changelog records for $cl_user failed"
17934         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17935         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17936                 error "Fail to start $SINGLEMDS"
17937         local cur_rec2=$(changelog_users $SINGLEMDS |
17938                          awk '/^current.index:/ { print $NF }')
17939         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17940         [ $cur_rec1 == $cur_rec2 ] ||
17941                 error "current index should be $cur_rec1 not $cur_rec2"
17942
17943         echo "verifying users from this test are deregistered"
17944         changelog_deregister || error "changelog_deregister failed"
17945         changelog_users $SINGLEMDS | grep -q $cl_user &&
17946                 error "User '$cl_user' still in changelog_users"
17947
17948         # lctl get_param -n mdd.*.changelog_users
17949         # current_index: 144
17950         # ID    index (idle seconds)
17951         # cl3   144   (2) mask=<list>
17952         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17953                 # this is the normal case where all users were deregistered
17954                 # make sure no new records are added when no users are present
17955                 local last_rec1=$(changelog_users $SINGLEMDS |
17956                                   awk '/^current.index:/ { print $NF }')
17957                 touch $DIR/$tdir/chloe
17958                 local last_rec2=$(changelog_users $SINGLEMDS |
17959                                   awk '/^current.index:/ { print $NF }')
17960                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17961                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17962         else
17963                 # any changelog users must be leftovers from a previous test
17964                 changelog_users $SINGLEMDS
17965                 echo "other changelog users; can't verify off"
17966         fi
17967 }
17968 run_test 160a "changelog sanity"
17969
17970 test_160b() { # LU-3587
17971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17972         remote_mds_nodsh && skip "remote MDS with nodsh"
17973         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17974                 skip "Need MDS version at least 2.2.0"
17975
17976         changelog_register || error "changelog_register failed"
17977         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17978         changelog_users $SINGLEMDS | grep -q $cl_user ||
17979                 error "User '$cl_user' not found in changelog_users"
17980
17981         local longname1=$(str_repeat a 255)
17982         local longname2=$(str_repeat b 255)
17983
17984         cd $DIR
17985         echo "creating very long named file"
17986         touch $longname1 || error "create of '$longname1' failed"
17987         echo "renaming very long named file"
17988         mv $longname1 $longname2
17989
17990         changelog_dump | grep RENME | tail -n 5
17991         rm -f $longname2
17992 }
17993 run_test 160b "Verify that very long rename doesn't crash in changelog"
17994
17995 test_160c() {
17996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17997         remote_mds_nodsh && skip "remote MDS with nodsh"
17998
17999         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18000                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18001                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18002                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18003
18004         local rc=0
18005
18006         # Registration step
18007         changelog_register || error "changelog_register failed"
18008
18009         rm -rf $DIR/$tdir
18010         mkdir -p $DIR/$tdir
18011         $MCREATE $DIR/$tdir/foo_160c
18012         changelog_chmask "-TRUNC"
18013         $TRUNCATE $DIR/$tdir/foo_160c 200
18014         changelog_chmask "+TRUNC"
18015         $TRUNCATE $DIR/$tdir/foo_160c 199
18016         changelog_dump | tail -n 5
18017         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
18018         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
18019 }
18020 run_test 160c "verify that changelog log catch the truncate event"
18021
18022 test_160d() {
18023         remote_mds_nodsh && skip "remote MDS with nodsh"
18024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18026         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
18027                 skip "Need MDS version at least 2.7.60"
18028
18029         # Registration step
18030         changelog_register || error "changelog_register failed"
18031
18032         mkdir -p $DIR/$tdir/migrate_dir
18033         changelog_clear 0 || error "changelog_clear failed"
18034
18035         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
18036         changelog_dump | tail -n 5
18037         local migrates=$(changelog_dump | grep -c "MIGRT")
18038         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
18039 }
18040 run_test 160d "verify that changelog log catch the migrate event"
18041
18042 test_160e() {
18043         remote_mds_nodsh && skip "remote MDS with nodsh"
18044
18045         # Create a user
18046         changelog_register || error "changelog_register failed"
18047
18048         local MDT0=$(facet_svc $SINGLEMDS)
18049         local rc
18050
18051         # No user (expect fail)
18052         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
18053         rc=$?
18054         if [ $rc -eq 0 ]; then
18055                 error "Should fail without user"
18056         elif [ $rc -ne 4 ]; then
18057                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
18058         fi
18059
18060         # Delete a future user (expect fail)
18061         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
18062         rc=$?
18063         if [ $rc -eq 0 ]; then
18064                 error "Deleted non-existant user cl77"
18065         elif [ $rc -ne 2 ]; then
18066                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
18067         fi
18068
18069         # Clear to a bad index (1 billion should be safe)
18070         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
18071         rc=$?
18072
18073         if [ $rc -eq 0 ]; then
18074                 error "Successfully cleared to invalid CL index"
18075         elif [ $rc -ne 22 ]; then
18076                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
18077         fi
18078 }
18079 run_test 160e "changelog negative testing (should return errors)"
18080
18081 test_160f() {
18082         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18083         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18084                 skip "Need MDS version at least 2.10.56"
18085
18086         local mdts=$(comma_list $(mdts_nodes))
18087
18088         # Create a user
18089         changelog_register || error "first changelog_register failed"
18090         changelog_register || error "second changelog_register failed"
18091         local cl_users
18092         declare -A cl_user1
18093         declare -A cl_user2
18094         local user_rec1
18095         local user_rec2
18096         local i
18097
18098         # generate some changelog records to accumulate on each MDT
18099         # use all_char because created files should be evenly distributed
18100         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18101                 error "test_mkdir $tdir failed"
18102         log "$(date +%s): creating first files"
18103         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18104                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
18105                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
18106         done
18107
18108         # check changelogs have been generated
18109         local start=$SECONDS
18110         local idle_time=$((MDSCOUNT * 5 + 5))
18111         local nbcl=$(changelog_dump | wc -l)
18112         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18113
18114         for param in "changelog_max_idle_time=$idle_time" \
18115                      "changelog_gc=1" \
18116                      "changelog_min_gc_interval=2" \
18117                      "changelog_min_free_cat_entries=3"; do
18118                 local MDT0=$(facet_svc $SINGLEMDS)
18119                 local var="${param%=*}"
18120                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18121
18122                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18123                 do_nodes $mdts $LCTL set_param mdd.*.$param
18124         done
18125
18126         # force cl_user2 to be idle (1st part), but also cancel the
18127         # cl_user1 records so that it is not evicted later in the test.
18128         local sleep1=$((idle_time / 2))
18129         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
18130         sleep $sleep1
18131
18132         # simulate changelog catalog almost full
18133         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
18134         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
18135
18136         for i in $(seq $MDSCOUNT); do
18137                 cl_users=(${CL_USERS[mds$i]})
18138                 cl_user1[mds$i]="${cl_users[0]}"
18139                 cl_user2[mds$i]="${cl_users[1]}"
18140
18141                 [ -n "${cl_user1[mds$i]}" ] ||
18142                         error "mds$i: no user registered"
18143                 [ -n "${cl_user2[mds$i]}" ] ||
18144                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18145
18146                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18147                 [ -n "$user_rec1" ] ||
18148                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18149                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18150                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18151                 [ -n "$user_rec2" ] ||
18152                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18153                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18154                      "$user_rec1 + 2 == $user_rec2"
18155                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18156                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18157                               "$user_rec1 + 2, but is $user_rec2"
18158                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18159                 [ -n "$user_rec2" ] ||
18160                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18161                 [ $user_rec1 == $user_rec2 ] ||
18162                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18163                               "$user_rec1, but is $user_rec2"
18164         done
18165
18166         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18167         local sleep2=$((idle_time - (SECONDS - start) + 1))
18168         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18169         sleep $sleep2
18170
18171         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18172         # cl_user1 should be OK because it recently processed records.
18173         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18174         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18175                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18176                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) 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: User ${cl_user1[mds$i]} not registered"
18190                 # check cl_user2 unregistered
18191                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18192                         error "mds$i: User ${cl_user2[mds$i]} still 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: User ${cl_user1[mds$i]} not registered"
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 160f "changelog garbage collect (timestamped users)"
18207
18208 test_160g() {
18209         remote_mds_nodsh && skip "remote MDS with nodsh"
18210         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18211                 skip "Need MDS version at least 2.14.55"
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 > 0 )) || error "no changelogs found"
18237
18238         # reduce the max_idle_indexes value to make sure we exceed it
18239         for param in "changelog_max_idle_indexes=2" \
18240                      "changelog_gc=1" \
18241                      "changelog_min_gc_interval=2"; do
18242                 local MDT0=$(facet_svc $SINGLEMDS)
18243                 local var="${param%=*}"
18244                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18245
18246                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18247                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18248                         error "unable to set mdd.*.$param"
18249         done
18250
18251         local start=$SECONDS
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: user1 is not registered"
18259                 [ -n "${cl_user2[mds$i]}" ] ||
18260                         error "mds$i: only ${cl_user1[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: user1 ${cl_user1[mds$i]} not found"
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: user1 ${cl_user1[mds$i]} not found (2)"
18269                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18270                      "$user_rec1 + 2 == $user_rec2"
18271                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18272                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18273                               "expected $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: user2 ${cl_user2[mds$i]} not found"
18277                 [ $user_rec1 == $user_rec2 ] ||
18278                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18279                               "expected $user_rec1, but is $user_rec2"
18280         done
18281
18282         # ensure we are past the previous changelog_min_gc_interval set above
18283         local sleep2=$((start + 2 - SECONDS))
18284         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18285         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18286         # cl_user1 should be OK because it recently processed records.
18287         for ((i = 0; i < MDSCOUNT; i++)); do
18288                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18289                         error "create $DIR/$tdir/d$i.3 failed"
18290         done
18291
18292         # ensure gc thread is done
18293         for i in $(mdts_nodes); do
18294                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18295                         error "$i: GC-thread not done"
18296         done
18297
18298         local first_rec
18299         for (( i = 1; i <= MDSCOUNT; i++ )); do
18300                 # check cl_user1 still registered
18301                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18302                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18303                 # check cl_user2 unregistered
18304                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18305                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18306
18307                 # check changelogs are present and starting at $user_rec1 + 1
18308                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18309                 [ -n "$user_rec1" ] ||
18310                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18311                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18312                             awk '{ print $1; exit; }')
18313
18314                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18315                 [ $((user_rec1 + 1)) == $first_rec ] ||
18316                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18317         done
18318 }
18319 run_test 160g "changelog garbage collect on idle records"
18320
18321 test_160h() {
18322         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18323         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18324                 skip "Need MDS version at least 2.10.56"
18325
18326         local mdts=$(comma_list $(mdts_nodes))
18327
18328         # Create a user
18329         changelog_register || error "first changelog_register failed"
18330         changelog_register || error "second changelog_register failed"
18331         local cl_users
18332         declare -A cl_user1
18333         declare -A cl_user2
18334         local user_rec1
18335         local user_rec2
18336         local i
18337
18338         # generate some changelog records to accumulate on each MDT
18339         # use all_char because created files should be evenly distributed
18340         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18341                 error "test_mkdir $tdir failed"
18342         for ((i = 0; i < MDSCOUNT; i++)); do
18343                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18344                         error "create $DIR/$tdir/d$i.1 failed"
18345         done
18346
18347         # check changelogs have been generated
18348         local nbcl=$(changelog_dump | wc -l)
18349         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18350
18351         for param in "changelog_max_idle_time=10" \
18352                      "changelog_gc=1" \
18353                      "changelog_min_gc_interval=2"; do
18354                 local MDT0=$(facet_svc $SINGLEMDS)
18355                 local var="${param%=*}"
18356                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18357
18358                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18359                 do_nodes $mdts $LCTL set_param mdd.*.$param
18360         done
18361
18362         # force cl_user2 to be idle (1st part)
18363         sleep 9
18364
18365         for i in $(seq $MDSCOUNT); do
18366                 cl_users=(${CL_USERS[mds$i]})
18367                 cl_user1[mds$i]="${cl_users[0]}"
18368                 cl_user2[mds$i]="${cl_users[1]}"
18369
18370                 [ -n "${cl_user1[mds$i]}" ] ||
18371                         error "mds$i: no user registered"
18372                 [ -n "${cl_user2[mds$i]}" ] ||
18373                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18374
18375                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18376                 [ -n "$user_rec1" ] ||
18377                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18378                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18379                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18380                 [ -n "$user_rec2" ] ||
18381                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18382                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18383                      "$user_rec1 + 2 == $user_rec2"
18384                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18385                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18386                               "$user_rec1 + 2, but is $user_rec2"
18387                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18388                 [ -n "$user_rec2" ] ||
18389                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18390                 [ $user_rec1 == $user_rec2 ] ||
18391                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18392                               "$user_rec1, but is $user_rec2"
18393         done
18394
18395         # force cl_user2 to be idle (2nd part) and to reach
18396         # changelog_max_idle_time
18397         sleep 2
18398
18399         # force each GC-thread start and block then
18400         # one per MDT/MDD, set fail_val accordingly
18401         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18402         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18403
18404         # generate more changelogs to trigger fail_loc
18405         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18406                 error "create $DIR/$tdir/${tfile}bis failed"
18407
18408         # stop MDT to stop GC-thread, should be done in back-ground as it will
18409         # block waiting for the thread to be released and exit
18410         declare -A stop_pids
18411         for i in $(seq $MDSCOUNT); do
18412                 stop mds$i &
18413                 stop_pids[mds$i]=$!
18414         done
18415
18416         for i in $(mdts_nodes); do
18417                 local facet
18418                 local nb=0
18419                 local facets=$(facets_up_on_host $i)
18420
18421                 for facet in ${facets//,/ }; do
18422                         if [[ $facet == mds* ]]; then
18423                                 nb=$((nb + 1))
18424                         fi
18425                 done
18426                 # ensure each MDS's gc threads are still present and all in "R"
18427                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18428                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18429                         error "$i: expected $nb GC-thread"
18430                 wait_update $i \
18431                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18432                         "R" 20 ||
18433                         error "$i: GC-thread not found in R-state"
18434                 # check umounts of each MDT on MDS have reached kthread_stop()
18435                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18436                         error "$i: expected $nb umount"
18437                 wait_update $i \
18438                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18439                         error "$i: umount not found in D-state"
18440         done
18441
18442         # release all GC-threads
18443         do_nodes $mdts $LCTL set_param fail_loc=0
18444
18445         # wait for MDT stop to complete
18446         for i in $(seq $MDSCOUNT); do
18447                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18448         done
18449
18450         # XXX
18451         # may try to check if any orphan changelog records are present
18452         # via ldiskfs/zfs and llog_reader...
18453
18454         # re-start/mount MDTs
18455         for i in $(seq $MDSCOUNT); do
18456                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18457                         error "Fail to start mds$i"
18458         done
18459
18460         local first_rec
18461         for i in $(seq $MDSCOUNT); do
18462                 # check cl_user1 still registered
18463                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18464                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18465                 # check cl_user2 unregistered
18466                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18467                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18468
18469                 # check changelogs are present and starting at $user_rec1 + 1
18470                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18471                 [ -n "$user_rec1" ] ||
18472                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18473                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18474                             awk '{ print $1; exit; }')
18475
18476                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18477                 [ $((user_rec1 + 1)) == $first_rec ] ||
18478                         error "mds$i: first index should be $user_rec1 + 1, " \
18479                               "but is $first_rec"
18480         done
18481 }
18482 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18483               "during mount"
18484
18485 test_160i() {
18486
18487         local mdts=$(comma_list $(mdts_nodes))
18488
18489         changelog_register || error "first changelog_register failed"
18490
18491         # generate some changelog records to accumulate on each MDT
18492         # use all_char because created files should be evenly distributed
18493         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18494                 error "test_mkdir $tdir failed"
18495         for ((i = 0; i < MDSCOUNT; i++)); do
18496                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18497                         error "create $DIR/$tdir/d$i.1 failed"
18498         done
18499
18500         # check changelogs have been generated
18501         local nbcl=$(changelog_dump | wc -l)
18502         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18503
18504         # simulate race between register and unregister
18505         # XXX as fail_loc is set per-MDS, with DNE configs the race
18506         # simulation will only occur for one MDT per MDS and for the
18507         # others the normal race scenario will take place
18508         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18509         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18510         do_nodes $mdts $LCTL set_param fail_val=1
18511
18512         # unregister 1st user
18513         changelog_deregister &
18514         local pid1=$!
18515         # wait some time for deregister work to reach race rdv
18516         sleep 2
18517         # register 2nd user
18518         changelog_register || error "2nd user register failed"
18519
18520         wait $pid1 || error "1st user deregister failed"
18521
18522         local i
18523         local last_rec
18524         declare -A LAST_REC
18525         for i in $(seq $MDSCOUNT); do
18526                 if changelog_users mds$i | grep "^cl"; then
18527                         # make sure new records are added with one user present
18528                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18529                                           awk '/^current.index:/ { print $NF }')
18530                 else
18531                         error "mds$i has no user registered"
18532                 fi
18533         done
18534
18535         # generate more changelog records to accumulate on each MDT
18536         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18537                 error "create $DIR/$tdir/${tfile}bis failed"
18538
18539         for i in $(seq $MDSCOUNT); do
18540                 last_rec=$(changelog_users $SINGLEMDS |
18541                            awk '/^current.index:/ { print $NF }')
18542                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18543                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18544                         error "changelogs are off on mds$i"
18545         done
18546 }
18547 run_test 160i "changelog user register/unregister race"
18548
18549 test_160j() {
18550         remote_mds_nodsh && skip "remote MDS with nodsh"
18551         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18552                 skip "Need MDS version at least 2.12.56"
18553
18554         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18555         stack_trap "umount $MOUNT2" EXIT
18556
18557         changelog_register || error "first changelog_register failed"
18558         stack_trap "changelog_deregister" EXIT
18559
18560         # generate some changelog
18561         # use all_char because created files should be evenly distributed
18562         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18563                 error "mkdir $tdir failed"
18564         for ((i = 0; i < MDSCOUNT; i++)); do
18565                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18566                         error "create $DIR/$tdir/d$i.1 failed"
18567         done
18568
18569         # open the changelog device
18570         exec 3>/dev/changelog-$FSNAME-MDT0000
18571         stack_trap "exec 3>&-" EXIT
18572         exec 4</dev/changelog-$FSNAME-MDT0000
18573         stack_trap "exec 4<&-" EXIT
18574
18575         # umount the first lustre mount
18576         umount $MOUNT
18577         stack_trap "mount_client $MOUNT" EXIT
18578
18579         # read changelog, which may or may not fail, but should not crash
18580         cat <&4 >/dev/null
18581
18582         # clear changelog
18583         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18584         changelog_users $SINGLEMDS | grep -q $cl_user ||
18585                 error "User $cl_user not found in changelog_users"
18586
18587         printf 'clear:'$cl_user':0' >&3
18588 }
18589 run_test 160j "client can be umounted while its chanangelog is being used"
18590
18591 test_160k() {
18592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18593         remote_mds_nodsh && skip "remote MDS with nodsh"
18594
18595         mkdir -p $DIR/$tdir/1/1
18596
18597         changelog_register || error "changelog_register failed"
18598         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18599
18600         changelog_users $SINGLEMDS | grep -q $cl_user ||
18601                 error "User '$cl_user' not found in changelog_users"
18602 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18603         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18604         rmdir $DIR/$tdir/1/1 & sleep 1
18605         mkdir $DIR/$tdir/2
18606         touch $DIR/$tdir/2/2
18607         rm -rf $DIR/$tdir/2
18608
18609         wait
18610         sleep 4
18611
18612         changelog_dump | grep rmdir || error "rmdir not recorded"
18613 }
18614 run_test 160k "Verify that changelog records are not lost"
18615
18616 # Verifies that a file passed as a parameter has recently had an operation
18617 # performed on it that has generated an MTIME changelog which contains the
18618 # correct parent FID. As files might reside on a different MDT from the
18619 # parent directory in DNE configurations, the FIDs are translated to paths
18620 # before being compared, which should be identical
18621 compare_mtime_changelog() {
18622         local file="${1}"
18623         local mdtidx
18624         local mtime
18625         local cl_fid
18626         local pdir
18627         local dir
18628
18629         mdtidx=$($LFS getstripe --mdt-index $file)
18630         mdtidx=$(printf "%04x" $mdtidx)
18631
18632         # Obtain the parent FID from the MTIME changelog
18633         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18634         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18635
18636         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18637         [ -z "$cl_fid" ] && error "parent FID not present"
18638
18639         # Verify that the path for the parent FID is the same as the path for
18640         # the test directory
18641         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18642
18643         dir=$(dirname $1)
18644
18645         [[ "${pdir%/}" == "$dir" ]] ||
18646                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18647 }
18648
18649 test_160l() {
18650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18651
18652         remote_mds_nodsh && skip "remote MDS with nodsh"
18653         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18654                 skip "Need MDS version at least 2.13.55"
18655
18656         local cl_user
18657
18658         changelog_register || error "changelog_register failed"
18659         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18660
18661         changelog_users $SINGLEMDS | grep -q $cl_user ||
18662                 error "User '$cl_user' not found in changelog_users"
18663
18664         # Clear some types so that MTIME changelogs are generated
18665         changelog_chmask "-CREAT"
18666         changelog_chmask "-CLOSE"
18667
18668         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18669
18670         # Test CL_MTIME during setattr
18671         touch $DIR/$tdir/$tfile
18672         compare_mtime_changelog $DIR/$tdir/$tfile
18673
18674         # Test CL_MTIME during close
18675         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18676         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18677 }
18678 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18679
18680 test_160m() {
18681         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18682         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18683                 skip "Need MDS version at least 2.14.51"
18684         local cl_users
18685         local cl_user1
18686         local cl_user2
18687         local pid1
18688
18689         # Create a user
18690         changelog_register || error "first changelog_register failed"
18691         changelog_register || error "second changelog_register failed"
18692
18693         cl_users=(${CL_USERS[mds1]})
18694         cl_user1="${cl_users[0]}"
18695         cl_user2="${cl_users[1]}"
18696         # generate some changelog records to accumulate on MDT0
18697         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18698         createmany -m $DIR/$tdir/$tfile 50 ||
18699                 error "create $DIR/$tdir/$tfile failed"
18700         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18701         rm -f $DIR/$tdir
18702
18703         # check changelogs have been generated
18704         local nbcl=$(changelog_dump | wc -l)
18705         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18706
18707 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18708         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18709
18710         __changelog_clear mds1 $cl_user1 +10
18711         __changelog_clear mds1 $cl_user2 0 &
18712         pid1=$!
18713         sleep 2
18714         __changelog_clear mds1 $cl_user1 0 ||
18715                 error "fail to cancel record for $cl_user1"
18716         wait $pid1
18717         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18718 }
18719 run_test 160m "Changelog clear race"
18720
18721 test_160n() {
18722         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18723         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18724                 skip "Need MDS version at least 2.14.51"
18725         local cl_users
18726         local cl_user1
18727         local pid1
18728         local first_rec
18729         local last_rec=0
18730
18731         # Create a user
18732         changelog_register || error "first changelog_register failed"
18733
18734         cl_users=(${CL_USERS[mds1]})
18735         cl_user1="${cl_users[0]}"
18736
18737         # generate some changelog records to accumulate on MDT0
18738         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18739         first_rec=$(changelog_users $SINGLEMDS |
18740                         awk '/^current.index:/ { print $NF }')
18741         while (( last_rec < (( first_rec + 65000)) )); do
18742                 createmany -m $DIR/$tdir/$tfile 10000 ||
18743                         error "create $DIR/$tdir/$tfile failed"
18744
18745                 for i in $(seq 0 10000); do
18746                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18747                                 > /dev/null
18748                 done
18749
18750                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18751                         error "unlinkmany failed unlink"
18752                 last_rec=$(changelog_users $SINGLEMDS |
18753                         awk '/^current.index:/ { print $NF }')
18754                 echo last record $last_rec
18755                 (( last_rec == 0 )) && error "no changelog found"
18756         done
18757
18758 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18759         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18760
18761         __changelog_clear mds1 $cl_user1 0 &
18762         pid1=$!
18763         sleep 2
18764         __changelog_clear mds1 $cl_user1 0 ||
18765                 error "fail to cancel record for $cl_user1 (forground)"
18766         wait $pid1
18767         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user1 (background)"
18768 }
18769 run_test 160n "Changelog destroy race"
18770
18771 test_160o() {
18772         local mdt="$(facet_svc $SINGLEMDS)"
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.52) ] ||
18777                 skip "Need MDS version at least 2.14.52"
18778
18779         changelog_register --user test_160o -m unlnk+close+open ||
18780                 error "changelog_register failed"
18781
18782         do_facet $SINGLEMDS $LCTL --device $mdt \
18783                                 changelog_register -u "Tt3_-#" &&
18784                 error "bad symbols in name should fail"
18785
18786         do_facet $SINGLEMDS $LCTL --device $mdt \
18787                                 changelog_register -u test_160o &&
18788                 error "the same name registration should fail"
18789
18790         do_facet $SINGLEMDS $LCTL --device $mdt \
18791                         changelog_register -u test_160toolongname &&
18792                 error "too long name registration should fail"
18793
18794         changelog_chmask "MARK+HSM"
18795         lctl get_param mdd.*.changelog*mask
18796         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18797         changelog_users $SINGLEMDS | grep -q $cl_user ||
18798                 error "User $cl_user not found in changelog_users"
18799         #verify username
18800         echo $cl_user | grep -q test_160o ||
18801                 error "User $cl_user has no specific name 'test160o'"
18802
18803         # change something
18804         changelog_clear 0 || error "changelog_clear failed"
18805         # generate some changelog records to accumulate on MDT0
18806         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18807         touch $DIR/$tdir/$tfile                 # open 1
18808
18809         OPENS=$(changelog_dump | grep -c "OPEN")
18810         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18811
18812         # must be no MKDIR it wasn't set as user mask
18813         MKDIR=$(changelog_dump | grep -c "MKDIR")
18814         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18815
18816         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18817                                 mdd.$mdt.changelog_current_mask -n)
18818         # register maskless user
18819         changelog_register || error "changelog_register failed"
18820         # effective mask should be not changed because it is not minimal
18821         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18822                                 mdd.$mdt.changelog_current_mask -n)
18823         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18824         # set server mask to minimal value
18825         changelog_chmask "MARK"
18826         # check effective mask again, should be treated as DEFMASK now
18827         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18828                                 mdd.$mdt.changelog_current_mask -n)
18829         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18830
18831         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18832                 # set server mask back to some value
18833                 changelog_chmask "CLOSE,UNLNK"
18834                 # check effective mask again, should not remain as DEFMASK
18835                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18836                                 mdd.$mdt.changelog_current_mask -n)
18837                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18838         fi
18839
18840         do_facet $SINGLEMDS $LCTL --device $mdt \
18841                                 changelog_deregister -u test_160o ||
18842                 error "cannot deregister by name"
18843 }
18844 run_test 160o "changelog user name and mask"
18845
18846 test_160p() {
18847         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18848         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18849                 skip "Need MDS version at least 2.14.51"
18850         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18851         local cl_users
18852         local cl_user1
18853         local entry_count
18854
18855         # Create a user
18856         changelog_register || error "first changelog_register failed"
18857
18858         cl_users=(${CL_USERS[mds1]})
18859         cl_user1="${cl_users[0]}"
18860
18861         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18862         createmany -m $DIR/$tdir/$tfile 50 ||
18863                 error "create $DIR/$tdir/$tfile failed"
18864         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18865         rm -rf $DIR/$tdir
18866
18867         # check changelogs have been generated
18868         entry_count=$(changelog_dump | wc -l)
18869         ((entry_count != 0)) || error "no changelog entries found"
18870
18871         # remove changelog_users and check that orphan entries are removed
18872         stop mds1
18873         local dev=$(mdsdevname 1)
18874         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18875         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18876         entry_count=$(changelog_dump | wc -l)
18877         ((entry_count == 0)) ||
18878                 error "found $entry_count changelog entries, expected none"
18879 }
18880 run_test 160p "Changelog orphan cleanup with no users"
18881
18882 test_160q() {
18883         local mdt="$(facet_svc $SINGLEMDS)"
18884         local clu
18885
18886         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18887         remote_mds_nodsh && skip "remote MDS with nodsh"
18888         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18889                 skip "Need MDS version at least 2.14.54"
18890
18891         # set server mask to minimal value like server init does
18892         changelog_chmask "MARK"
18893         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18894                 error "changelog_register failed"
18895         # check effective mask again, should be treated as DEFMASK now
18896         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18897                                 mdd.$mdt.changelog_current_mask -n)
18898         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18899                 error "changelog_deregister failed"
18900         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18901 }
18902 run_test 160q "changelog effective mask is DEFMASK if not set"
18903
18904 test_160s() {
18905         remote_mds_nodsh && skip "remote MDS with nodsh"
18906         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18907                 skip "Need MDS version at least 2.14.55"
18908
18909         local mdts=$(comma_list $(mdts_nodes))
18910
18911         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18912         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18913                                        fail_val=$((24 * 3600 * 10))
18914
18915         # Create a user which is 10 days old
18916         changelog_register || error "first changelog_register failed"
18917         local cl_users
18918         declare -A cl_user1
18919         local i
18920
18921         # generate some changelog records to accumulate on each MDT
18922         # use all_char because created files should be evenly distributed
18923         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18924                 error "test_mkdir $tdir failed"
18925         for ((i = 0; i < MDSCOUNT; i++)); do
18926                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18927                         error "create $DIR/$tdir/d$i.1 failed"
18928         done
18929
18930         # check changelogs have been generated
18931         local nbcl=$(changelog_dump | wc -l)
18932         (( nbcl > 0 )) || error "no changelogs found"
18933
18934         # reduce the max_idle_indexes value to make sure we exceed it
18935         for param in "changelog_max_idle_indexes=2097446912" \
18936                      "changelog_max_idle_time=2592000" \
18937                      "changelog_gc=1" \
18938                      "changelog_min_gc_interval=2"; do
18939                 local MDT0=$(facet_svc $SINGLEMDS)
18940                 local var="${param%=*}"
18941                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18942
18943                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18944                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18945                         error "unable to set mdd.*.$param"
18946         done
18947
18948         local start=$SECONDS
18949         for i in $(seq $MDSCOUNT); do
18950                 cl_users=(${CL_USERS[mds$i]})
18951                 cl_user1[mds$i]="${cl_users[0]}"
18952
18953                 [[ -n "${cl_user1[mds$i]}" ]] ||
18954                         error "mds$i: no user registered"
18955         done
18956
18957         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18958         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18959
18960         # ensure we are past the previous changelog_min_gc_interval set above
18961         local sleep2=$((start + 2 - SECONDS))
18962         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18963
18964         # Generate one more changelog to trigger GC
18965         for ((i = 0; i < MDSCOUNT; i++)); do
18966                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18967                         error "create $DIR/$tdir/d$i.3 failed"
18968         done
18969
18970         # ensure gc thread is done
18971         for node in $(mdts_nodes); do
18972                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18973                         error "$node: GC-thread not done"
18974         done
18975
18976         do_nodes $mdts $LCTL set_param fail_loc=0
18977
18978         for (( i = 1; i <= MDSCOUNT; i++ )); do
18979                 # check cl_user1 is purged
18980                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18981                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18982         done
18983         return 0
18984 }
18985 run_test 160s "changelog garbage collect on idle records * time"
18986
18987 test_160t() {
18988         remote_mds_nodsh && skip "remote MDS with nodsh"
18989         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18990                 skip "Need MDS version at least 2.15.50"
18991
18992         local MDT0=$(facet_svc $SINGLEMDS)
18993         local cl_users
18994         local cl_user1
18995         local cl_user2
18996         local start
18997
18998         changelog_register --user user1 -m all ||
18999                 error "user1 failed to register"
19000
19001         mkdir_on_mdt0 $DIR/$tdir
19002         # create default overstripe to maximize changelog size
19003         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
19004         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
19005         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
19006
19007         # user2 consumes less records so less space
19008         changelog_register --user user2 || error "user2 failed to register"
19009         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
19010         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
19011
19012         # check changelogs have been generated
19013         local nbcl=$(changelog_dump | wc -l)
19014         (( nbcl > 0 )) || error "no changelogs found"
19015
19016         # reduce the changelog_min_gc_interval to force check
19017         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
19018                 local var="${param%=*}"
19019                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
19020
19021                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
19022                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
19023                         error "unable to set mdd.*.$param"
19024         done
19025
19026         start=$SECONDS
19027         cl_users=(${CL_USERS[mds1]})
19028         cl_user1="${cl_users[0]}"
19029         cl_user2="${cl_users[1]}"
19030
19031         [[ -n $cl_user1 ]] ||
19032                 error "mds1: user #1 isn't registered"
19033         [[ -n $cl_user2 ]] ||
19034                 error "mds1: user #2 isn't registered"
19035
19036         # ensure we are past the previous changelog_min_gc_interval set above
19037         local sleep2=$((start + 2 - SECONDS))
19038         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
19039
19040         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
19041         do_facet mds1 $LCTL set_param fail_loc=0x018c \
19042                         fail_val=$(((llog_size1 + llog_size2) / 2))
19043
19044         # Generate more changelog to trigger GC
19045         createmany -o $DIR/$tdir/u3_ 4 ||
19046                 error "create failed for more files"
19047
19048         # ensure gc thread is done
19049         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
19050                 error "mds1: GC-thread not done"
19051
19052         do_facet mds1 $LCTL set_param fail_loc=0
19053
19054         # check cl_user1 is purged
19055         changelog_users mds1 | grep -q "$cl_user1" &&
19056                 error "User $cl_user1 is registered"
19057         # check cl_user2 is not purged
19058         changelog_users mds1 | grep -q "$cl_user2" ||
19059                 error "User $cl_user2 is not registered"
19060 }
19061 run_test 160t "changelog garbage collect on lack of space"
19062
19063 test_160u() { # LU-17400
19064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19065         remote_mds_nodsh && skip "remote MDS with nodsh"
19066         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
19067                 skip "Need MDS version at least 2.2.0"
19068
19069         cd $DIR || error "cd $DIR failed"
19070
19071         # ensure changelog has a clean view if tests are run multiple times
19072         [ -d rename ] && rm -rf rename
19073
19074         changelog_register || error "changelog_register failed"
19075         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
19076
19077         changelog_users $SINGLEMDS | grep -q $cl_user ||
19078                 error "User '$cl_user' not found in changelog_users"
19079
19080         local longname1=$(str_repeat a 255)
19081
19082         echo "creating simple directory tree"
19083         mkdir -p rename/a || error "create of simple directory tree failed"
19084         echo "creating rename/hw file"
19085         echo "hello world" > rename/hw || error "create of rename/hw failed"
19086         echo "creating very long named file"
19087         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
19088         echo "move rename/hw to rename/a/a.hw"
19089         mv rename/hw rename/a/a.hw || error "mv failed"
19090
19091         RENME=($(changelog_dump | grep "RENME"))
19092         #declare -p RENME # for debugging captured value with indexes
19093
19094         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
19095                 error "changelog rename record type name/sname error"
19096 }
19097 run_test 160u "changelog rename record type name and sname strings are correct"
19098
19099 test_161a() {
19100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19101
19102         test_mkdir -c1 $DIR/$tdir
19103         cp /etc/hosts $DIR/$tdir/$tfile
19104         test_mkdir -c1 $DIR/$tdir/foo1
19105         test_mkdir -c1 $DIR/$tdir/foo2
19106         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
19107         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
19108         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
19109         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
19110         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
19111         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19112                 $LFS fid2path $DIR $FID
19113                 error "bad link ea"
19114         fi
19115         # middle
19116         rm $DIR/$tdir/foo2/zachary
19117         # last
19118         rm $DIR/$tdir/foo2/thor
19119         # first
19120         rm $DIR/$tdir/$tfile
19121         # rename
19122         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
19123         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
19124                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
19125         rm $DIR/$tdir/foo2/maggie
19126
19127         # overflow the EA
19128         local longname=$tfile.avg_len_is_thirty_two_
19129         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
19130                 error_noexit 'failed to unlink many hardlinks'" EXIT
19131         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
19132                 error "failed to hardlink many files"
19133         links=$($LFS fid2path $DIR $FID | wc -l)
19134         echo -n "${links}/1000 links in link EA"
19135         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
19136 }
19137 run_test 161a "link ea sanity"
19138
19139 test_161b() {
19140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19141         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
19142
19143         local MDTIDX=1
19144         local remote_dir=$DIR/$tdir/remote_dir
19145
19146         mkdir -p $DIR/$tdir
19147         $LFS mkdir -i $MDTIDX $remote_dir ||
19148                 error "create remote directory failed"
19149
19150         cp /etc/hosts $remote_dir/$tfile
19151         mkdir -p $remote_dir/foo1
19152         mkdir -p $remote_dir/foo2
19153         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19154         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19155         ln $remote_dir/$tfile $remote_dir/foo1/luna
19156         ln $remote_dir/$tfile $remote_dir/foo2/thor
19157
19158         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19159                      tr -d ']')
19160         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19161                 $LFS fid2path $DIR $FID
19162                 error "bad link ea"
19163         fi
19164         # middle
19165         rm $remote_dir/foo2/zachary
19166         # last
19167         rm $remote_dir/foo2/thor
19168         # first
19169         rm $remote_dir/$tfile
19170         # rename
19171         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19172         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19173         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19174                 $LFS fid2path $DIR $FID
19175                 error "bad link rename"
19176         fi
19177         rm $remote_dir/foo2/maggie
19178
19179         # overflow the EA
19180         local longname=filename_avg_len_is_thirty_two_
19181         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19182                 error "failed to hardlink many files"
19183         links=$($LFS fid2path $DIR $FID | wc -l)
19184         echo -n "${links}/1000 links in link EA"
19185         [[ ${links} -gt 60 ]] ||
19186                 error "expected at least 60 links in link EA"
19187         unlinkmany $remote_dir/foo2/$longname 1000 ||
19188         error "failed to unlink many hardlinks"
19189 }
19190 run_test 161b "link ea sanity under remote directory"
19191
19192 test_161c() {
19193         remote_mds_nodsh && skip "remote MDS with nodsh"
19194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19195         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19196                 skip "Need MDS version at least 2.1.5"
19197
19198         # define CLF_RENAME_LAST 0x0001
19199         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19200         changelog_register || error "changelog_register failed"
19201
19202         rm -rf $DIR/$tdir
19203         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19204         touch $DIR/$tdir/foo_161c
19205         touch $DIR/$tdir/bar_161c
19206         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19207         changelog_dump | grep RENME | tail -n 5
19208         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19209         changelog_clear 0 || error "changelog_clear failed"
19210         if [ x$flags != "x0x1" ]; then
19211                 error "flag $flags is not 0x1"
19212         fi
19213
19214         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19215         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19216         touch $DIR/$tdir/foo_161c
19217         touch $DIR/$tdir/bar_161c
19218         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19219         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19220         changelog_dump | grep RENME | tail -n 5
19221         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19222         changelog_clear 0 || error "changelog_clear failed"
19223         if [ x$flags != "x0x0" ]; then
19224                 error "flag $flags is not 0x0"
19225         fi
19226         echo "rename overwrite a target having nlink > 1," \
19227                 "changelog record has flags of $flags"
19228
19229         # rename doesn't overwrite a target (changelog flag 0x0)
19230         touch $DIR/$tdir/foo_161c
19231         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19232         changelog_dump | grep RENME | tail -n 5
19233         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19234         changelog_clear 0 || error "changelog_clear failed"
19235         if [ x$flags != "x0x0" ]; then
19236                 error "flag $flags is not 0x0"
19237         fi
19238         echo "rename doesn't overwrite a target," \
19239                 "changelog record has flags of $flags"
19240
19241         # define CLF_UNLINK_LAST 0x0001
19242         # unlink a file having nlink = 1 (changelog flag 0x1)
19243         rm -f $DIR/$tdir/foo2_161c
19244         changelog_dump | grep UNLNK | tail -n 5
19245         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19246         changelog_clear 0 || error "changelog_clear failed"
19247         if [ x$flags != "x0x1" ]; then
19248                 error "flag $flags is not 0x1"
19249         fi
19250         echo "unlink a file having nlink = 1," \
19251                 "changelog record has flags of $flags"
19252
19253         # unlink a file having nlink > 1 (changelog flag 0x0)
19254         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19255         rm -f $DIR/$tdir/foobar_161c
19256         changelog_dump | grep UNLNK | tail -n 5
19257         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19258         changelog_clear 0 || error "changelog_clear failed"
19259         if [ x$flags != "x0x0" ]; then
19260                 error "flag $flags is not 0x0"
19261         fi
19262         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19263 }
19264 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19265
19266 test_161d() {
19267         remote_mds_nodsh && skip "remote MDS with nodsh"
19268         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19269
19270         local pid
19271         local fid
19272
19273         changelog_register || error "changelog_register failed"
19274
19275         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19276         # interfer with $MOUNT/.lustre/fid/ access
19277         mkdir $DIR/$tdir
19278         [[ $? -eq 0 ]] || error "mkdir failed"
19279
19280         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19281         $LCTL set_param fail_loc=0x8000140c
19282         # 5s pause
19283         $LCTL set_param fail_val=5
19284
19285         # create file
19286         echo foofoo > $DIR/$tdir/$tfile &
19287         pid=$!
19288
19289         # wait for create to be delayed
19290         sleep 2
19291
19292         ps -p $pid
19293         [[ $? -eq 0 ]] || error "create should be blocked"
19294
19295         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19296         stack_trap "rm -f $tempfile"
19297         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19298         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19299         # some delay may occur during ChangeLog publishing and file read just
19300         # above, that could allow file write to happen finally
19301         [[ -s $tempfile ]] && echo "file should be empty"
19302
19303         $LCTL set_param fail_loc=0
19304
19305         wait $pid
19306         [[ $? -eq 0 ]] || error "create failed"
19307 }
19308 run_test 161d "create with concurrent .lustre/fid access"
19309
19310 check_path() {
19311         local expected="$1"
19312         shift
19313         local fid="$2"
19314
19315         local path
19316         path=$($LFS fid2path "$@")
19317         local rc=$?
19318
19319         if [ $rc -ne 0 ]; then
19320                 error "path looked up of '$expected' failed: rc=$rc"
19321         elif [ "$path" != "$expected" ]; then
19322                 error "path looked up '$path' instead of '$expected'"
19323         else
19324                 echo "FID '$fid' resolves to path '$path' as expected"
19325         fi
19326 }
19327
19328 test_162a() { # was test_162
19329         test_mkdir -p -c1 $DIR/$tdir/d2
19330         touch $DIR/$tdir/d2/$tfile
19331         touch $DIR/$tdir/d2/x1
19332         touch $DIR/$tdir/d2/x2
19333         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19334         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19335         # regular file
19336         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19337         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19338
19339         # softlink
19340         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19341         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19342         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19343
19344         # softlink to wrong file
19345         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19346         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19347         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19348
19349         # hardlink
19350         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19351         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19352         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19353         # fid2path dir/fsname should both work
19354         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19355         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19356
19357         # hardlink count: check that there are 2 links
19358         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19359         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19360
19361         # hardlink indexing: remove the first link
19362         rm $DIR/$tdir/d2/p/q/r/hlink
19363         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19364 }
19365 run_test 162a "path lookup sanity"
19366
19367 test_162b() {
19368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19369         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19370
19371         mkdir $DIR/$tdir
19372         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19373                                 error "create striped dir failed"
19374
19375         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19376                                         tail -n 1 | awk '{print $2}')
19377         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19378
19379         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19380         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19381
19382         # regular file
19383         for ((i=0;i<5;i++)); do
19384                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19385                         error "get fid for f$i failed"
19386                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19387
19388                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19389                         error "get fid for d$i failed"
19390                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19391         done
19392
19393         return 0
19394 }
19395 run_test 162b "striped directory path lookup sanity"
19396
19397 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19398 test_162c() {
19399         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19400                 skip "Need MDS version at least 2.7.51"
19401
19402         local lpath=$tdir.local
19403         local rpath=$tdir.remote
19404
19405         test_mkdir $DIR/$lpath
19406         test_mkdir $DIR/$rpath
19407
19408         for ((i = 0; i <= 101; i++)); do
19409                 lpath="$lpath/$i"
19410                 mkdir $DIR/$lpath
19411                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19412                         error "get fid for local directory $DIR/$lpath failed"
19413                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19414
19415                 rpath="$rpath/$i"
19416                 test_mkdir $DIR/$rpath
19417                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19418                         error "get fid for remote directory $DIR/$rpath failed"
19419                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19420         done
19421
19422         return 0
19423 }
19424 run_test 162c "fid2path works with paths 100 or more directories deep"
19425
19426 oalr_event_count() {
19427         local event="${1}"
19428         local trace="${2}"
19429
19430         awk -v name="${FSNAME}-OST0000" \
19431             -v event="${event}" \
19432             '$1 == "TRACE" && $2 == event && $3 == name' \
19433             "${trace}" |
19434         wc -l
19435 }
19436
19437 oalr_expect_event_count() {
19438         local event="${1}"
19439         local trace="${2}"
19440         local expect="${3}"
19441         local count
19442
19443         count=$(oalr_event_count "${event}" "${trace}")
19444         if ((count == expect)); then
19445                 return 0
19446         fi
19447
19448         error_noexit "${event} event count was '${count}', expected ${expect}"
19449         cat "${trace}" >&2
19450         exit 1
19451 }
19452
19453 cleanup_165() {
19454         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19455         stop ost1
19456         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19457 }
19458
19459 setup_165() {
19460         sync # Flush previous IOs so we can count log entries.
19461         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19462         stack_trap cleanup_165 EXIT
19463 }
19464
19465 test_165a() {
19466         local trace="/tmp/${tfile}.trace"
19467         local rc
19468         local count
19469
19470         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19471                 skip "OFD access log unsupported"
19472
19473         setup_165
19474         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19475         sleep 5
19476
19477         do_facet ost1 ofd_access_log_reader --list
19478         stop ost1
19479
19480         do_facet ost1 killall -TERM ofd_access_log_reader
19481         wait
19482         rc=$?
19483
19484         if ((rc != 0)); then
19485                 error "ofd_access_log_reader exited with rc = '${rc}'"
19486         fi
19487
19488         # Parse trace file for discovery events:
19489         oalr_expect_event_count alr_log_add "${trace}" 1
19490         oalr_expect_event_count alr_log_eof "${trace}" 1
19491         oalr_expect_event_count alr_log_free "${trace}" 1
19492 }
19493 run_test 165a "ofd access log discovery"
19494
19495 test_165b() {
19496         local trace="/tmp/${tfile}.trace"
19497         local file="${DIR}/${tfile}"
19498         local pfid1
19499         local pfid2
19500         local -a entry
19501         local rc
19502         local count
19503         local size
19504         local flags
19505
19506         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19507                 skip "OFD access log unsupported"
19508
19509         setup_165
19510         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19511         sleep 5
19512
19513         do_facet ost1 ofd_access_log_reader --list
19514
19515         lfs setstripe -c 1 -i 0 "${file}"
19516         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19517                 error "cannot create '${file}'"
19518
19519         sleep 5
19520         do_facet ost1 killall -TERM ofd_access_log_reader
19521         wait
19522         rc=$?
19523
19524         if ((rc != 0)); then
19525                 error "ofd_access_log_reader exited with rc = '${rc}'"
19526         fi
19527
19528         oalr_expect_event_count alr_log_entry "${trace}" 1
19529
19530         pfid1=$($LFS path2fid "${file}")
19531
19532         # 1     2             3   4    5     6   7    8    9     10
19533         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19534         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19535
19536         echo "entry = '${entry[*]}'" >&2
19537
19538         pfid2=${entry[4]}
19539         if [[ "${pfid1}" != "${pfid2}" ]]; then
19540                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19541         fi
19542
19543         size=${entry[8]}
19544         if ((size != 1048576)); then
19545                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19546         fi
19547
19548         flags=${entry[10]}
19549         if [[ "${flags}" != "w" ]]; then
19550                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19551         fi
19552
19553         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19554         sleep 5
19555
19556         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19557                 error "cannot read '${file}'"
19558         sleep 5
19559
19560         do_facet ost1 killall -TERM ofd_access_log_reader
19561         wait
19562         rc=$?
19563
19564         if ((rc != 0)); then
19565                 error "ofd_access_log_reader exited with rc = '${rc}'"
19566         fi
19567
19568         oalr_expect_event_count alr_log_entry "${trace}" 1
19569
19570         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19571         echo "entry = '${entry[*]}'" >&2
19572
19573         pfid2=${entry[4]}
19574         if [[ "${pfid1}" != "${pfid2}" ]]; then
19575                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19576         fi
19577
19578         size=${entry[8]}
19579         if ((size != 524288)); then
19580                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19581         fi
19582
19583         flags=${entry[10]}
19584         if [[ "${flags}" != "r" ]]; then
19585                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19586         fi
19587 }
19588 run_test 165b "ofd access log entries are produced and consumed"
19589
19590 test_165c() {
19591         local trace="/tmp/${tfile}.trace"
19592         local file="${DIR}/${tdir}/${tfile}"
19593
19594         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19595                 skip "OFD access log unsupported"
19596
19597         test_mkdir "${DIR}/${tdir}"
19598
19599         setup_165
19600         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19601         sleep 5
19602
19603         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19604
19605         # 4096 / 64 = 64. Create twice as many entries.
19606         for ((i = 0; i < 128; i++)); do
19607                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19608                         error "cannot create file"
19609         done
19610
19611         sync
19612
19613         do_facet ost1 killall -TERM ofd_access_log_reader
19614         wait
19615         rc=$?
19616         if ((rc != 0)); then
19617                 error "ofd_access_log_reader exited with rc = '${rc}'"
19618         fi
19619
19620         unlinkmany  "${file}-%d" 128
19621 }
19622 run_test 165c "full ofd access logs do not block IOs"
19623
19624 oal_get_read_count() {
19625         local stats="$1"
19626
19627         # STATS lustre-OST0001 alr_read_count 1
19628
19629         do_facet ost1 cat "${stats}" |
19630         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19631              END { print count; }'
19632 }
19633
19634 oal_expect_read_count() {
19635         local stats="$1"
19636         local count
19637         local expect="$2"
19638
19639         # Ask ofd_access_log_reader to write stats.
19640         do_facet ost1 killall -USR1 ofd_access_log_reader
19641
19642         # Allow some time for things to happen.
19643         sleep 1
19644
19645         count=$(oal_get_read_count "${stats}")
19646         if ((count == expect)); then
19647                 return 0
19648         fi
19649
19650         error_noexit "bad read count, got ${count}, expected ${expect}"
19651         do_facet ost1 cat "${stats}" >&2
19652         exit 1
19653 }
19654
19655 test_165d() {
19656         local stats="/tmp/${tfile}.stats"
19657         local file="${DIR}/${tdir}/${tfile}"
19658         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19659
19660         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19661                 skip "OFD access log unsupported"
19662
19663         test_mkdir "${DIR}/${tdir}"
19664
19665         setup_165
19666         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19667         sleep 5
19668
19669         lfs setstripe -c 1 -i 0 "${file}"
19670
19671         do_facet ost1 lctl set_param "${param}=rw"
19672         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19673                 error "cannot create '${file}'"
19674         oal_expect_read_count "${stats}" 1
19675
19676         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19677                 error "cannot read '${file}'"
19678         oal_expect_read_count "${stats}" 2
19679
19680         do_facet ost1 lctl set_param "${param}=r"
19681         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19682                 error "cannot create '${file}'"
19683         oal_expect_read_count "${stats}" 2
19684
19685         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19686                 error "cannot read '${file}'"
19687         oal_expect_read_count "${stats}" 3
19688
19689         do_facet ost1 lctl set_param "${param}=w"
19690         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19691                 error "cannot create '${file}'"
19692         oal_expect_read_count "${stats}" 4
19693
19694         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19695                 error "cannot read '${file}'"
19696         oal_expect_read_count "${stats}" 4
19697
19698         do_facet ost1 lctl set_param "${param}=0"
19699         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19700                 error "cannot create '${file}'"
19701         oal_expect_read_count "${stats}" 4
19702
19703         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19704                 error "cannot read '${file}'"
19705         oal_expect_read_count "${stats}" 4
19706
19707         do_facet ost1 killall -TERM ofd_access_log_reader
19708         wait
19709         rc=$?
19710         if ((rc != 0)); then
19711                 error "ofd_access_log_reader exited with rc = '${rc}'"
19712         fi
19713 }
19714 run_test 165d "ofd_access_log mask works"
19715
19716 test_165e() {
19717         local stats="/tmp/${tfile}.stats"
19718         local file0="${DIR}/${tdir}-0/${tfile}"
19719         local file1="${DIR}/${tdir}-1/${tfile}"
19720
19721         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19722                 skip "OFD access log unsupported"
19723
19724         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19725
19726         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19727         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19728
19729         lfs setstripe -c 1 -i 0 "${file0}"
19730         lfs setstripe -c 1 -i 0 "${file1}"
19731
19732         setup_165
19733         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19734         sleep 5
19735
19736         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19737                 error "cannot create '${file0}'"
19738         sync
19739         oal_expect_read_count "${stats}" 0
19740
19741         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19742                 error "cannot create '${file1}'"
19743         sync
19744         oal_expect_read_count "${stats}" 1
19745
19746         do_facet ost1 killall -TERM ofd_access_log_reader
19747         wait
19748         rc=$?
19749         if ((rc != 0)); then
19750                 error "ofd_access_log_reader exited with rc = '${rc}'"
19751         fi
19752 }
19753 run_test 165e "ofd_access_log MDT index filter works"
19754
19755 test_165f() {
19756         local trace="/tmp/${tfile}.trace"
19757         local rc
19758         local count
19759
19760         setup_165
19761         do_facet ost1 timeout 60 ofd_access_log_reader \
19762                 --exit-on-close --debug=- --trace=- > "${trace}" &
19763         sleep 5
19764         stop ost1
19765
19766         wait
19767         rc=$?
19768
19769         if ((rc != 0)); then
19770                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19771                 cat "${trace}"
19772                 exit 1
19773         fi
19774 }
19775 run_test 165f "ofd_access_log_reader --exit-on-close works"
19776
19777 test_169() {
19778         # do directio so as not to populate the page cache
19779         log "creating a 10 Mb file"
19780         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19781                 error "multiop failed while creating a file"
19782         log "starting reads"
19783         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19784         log "truncating the file"
19785         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19786                 error "multiop failed while truncating the file"
19787         log "killing dd"
19788         kill %+ || true # reads might have finished
19789         echo "wait until dd is finished"
19790         wait
19791         log "removing the temporary file"
19792         rm -rf $DIR/$tfile || error "tmp file removal failed"
19793 }
19794 run_test 169 "parallel read and truncate should not deadlock"
19795
19796 test_170() {
19797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19798
19799         $LCTL clear     # bug 18514
19800         $LCTL debug_daemon start $TMP/${tfile}_log_good
19801         touch $DIR/$tfile
19802         $LCTL debug_daemon stop
19803         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19804                 error "sed failed to read log_good"
19805
19806         $LCTL debug_daemon start $TMP/${tfile}_log_good
19807         rm -rf $DIR/$tfile
19808         $LCTL debug_daemon stop
19809
19810         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19811                error "lctl df log_bad failed"
19812
19813         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19814         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19815
19816         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19817         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19818
19819         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19820                 error "bad_line good_line1 good_line2 are empty"
19821
19822         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19823         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19824         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19825
19826         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19827         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19828         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19829
19830         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19831                 error "bad_line_new good_line_new are empty"
19832
19833         local expected_good=$((good_line1 + good_line2*2))
19834
19835         rm -f $TMP/${tfile}*
19836         # LU-231, short malformed line may not be counted into bad lines
19837         if [ $bad_line -ne $bad_line_new ] &&
19838                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19839                 error "expected $bad_line bad lines, but got $bad_line_new"
19840                 return 1
19841         fi
19842
19843         if [ $expected_good -ne $good_line_new ]; then
19844                 error "expected $expected_good good lines, but got $good_line_new"
19845                 return 2
19846         fi
19847         true
19848 }
19849 run_test 170 "test lctl df to handle corrupted log ====================="
19850
19851 test_171() { # bug20592
19852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19853
19854         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19855         $LCTL set_param fail_loc=0x50e
19856         $LCTL set_param fail_val=3000
19857         multiop_bg_pause $DIR/$tfile O_s || true
19858         local MULTIPID=$!
19859         kill -USR1 $MULTIPID
19860         # cause log dump
19861         sleep 3
19862         wait $MULTIPID
19863         if dmesg | grep "recursive fault"; then
19864                 error "caught a recursive fault"
19865         fi
19866         $LCTL set_param fail_loc=0
19867         true
19868 }
19869 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19870
19871 test_172() {
19872
19873         #define OBD_FAIL_OBD_CLEANUP  0x60e
19874         $LCTL set_param fail_loc=0x60e
19875         umount $MOUNT || error "umount $MOUNT failed"
19876         stack_trap "mount_client $MOUNT"
19877
19878         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19879                 error "no client OBDs are remained"
19880
19881         $LCTL dl | while read devno state type name foo; do
19882                 case $type in
19883                 lov|osc|lmv|mdc)
19884                         $LCTL --device $name cleanup
19885                         $LCTL --device $name detach
19886                         ;;
19887                 *)
19888                         # skip server devices
19889                         ;;
19890                 esac
19891         done
19892
19893         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19894                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19895                 error "some client OBDs are still remained"
19896         fi
19897
19898 }
19899 run_test 172 "manual device removal with lctl cleanup/detach ======"
19900
19901 # it would be good to share it with obdfilter-survey/iokit-libecho code
19902 setup_obdecho_osc () {
19903         local rc=0
19904         local ost_nid=$1
19905         local obdfilter_name=$2
19906         echo "Creating new osc for $obdfilter_name on $ost_nid"
19907         # make sure we can find loopback nid
19908         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19909
19910         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19911                            ${obdfilter_name}_osc_UUID || rc=2; }
19912         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19913                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19914         return $rc
19915 }
19916
19917 cleanup_obdecho_osc () {
19918         local obdfilter_name=$1
19919         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19920         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19921         return 0
19922 }
19923
19924 obdecho_test() {
19925         local OBD=$1
19926         local node=$2
19927         local pages=${3:-64}
19928         local rc=0
19929         local id
19930
19931         local count=10
19932         local obd_size=$(get_obd_size $node $OBD)
19933         local page_size=$(get_page_size $node)
19934         if [[ -n "$obd_size" ]]; then
19935                 local new_count=$((obd_size / (pages * page_size / 1024)))
19936                 [[ $new_count -ge $count ]] || count=$new_count
19937         fi
19938
19939         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19940         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19941                            rc=2; }
19942         if [ $rc -eq 0 ]; then
19943             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19944             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19945         fi
19946         echo "New object id is $id"
19947         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19948                            rc=4; }
19949         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19950                            "test_brw $count w v $pages $id" || rc=4; }
19951         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19952                            rc=4; }
19953         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19954                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19955         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19956                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19957         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19958         return $rc
19959 }
19960
19961 test_180a() {
19962         skip "obdecho on osc is no longer supported"
19963 }
19964 run_test 180a "test obdecho on osc"
19965
19966 test_180b() {
19967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19968         remote_ost_nodsh && skip "remote OST with nodsh"
19969
19970         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19971                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19972                 error "failed to load module obdecho"
19973
19974         local target=$(do_facet ost1 $LCTL dl |
19975                        awk '/obdfilter/ { print $4; exit; }')
19976
19977         if [ -n "$target" ]; then
19978                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19979         else
19980                 do_facet ost1 $LCTL dl
19981                 error "there is no obdfilter target on ost1"
19982         fi
19983 }
19984 run_test 180b "test obdecho directly on obdfilter"
19985
19986 test_180c() { # LU-2598
19987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19988         remote_ost_nodsh && skip "remote OST with nodsh"
19989         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19990                 skip "Need MDS version at least 2.4.0"
19991
19992         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19993                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19994                 error "failed to load module obdecho"
19995
19996         local target=$(do_facet ost1 $LCTL dl |
19997                        awk '/obdfilter/ { print $4; exit; }')
19998
19999         if [ -n "$target" ]; then
20000                 local pages=16384 # 64MB bulk I/O RPC size
20001
20002                 obdecho_test "$target" ost1 "$pages" ||
20003                         error "obdecho_test with pages=$pages failed with $?"
20004         else
20005                 do_facet ost1 $LCTL dl
20006                 error "there is no obdfilter target on ost1"
20007         fi
20008 }
20009 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
20010
20011 test_181() { # bug 22177
20012         test_mkdir $DIR/$tdir
20013         # create enough files to index the directory
20014         createmany -o $DIR/$tdir/foobar 4000
20015         # print attributes for debug purpose
20016         lsattr -d .
20017         # open dir
20018         multiop_bg_pause $DIR/$tdir D_Sc || return 1
20019         MULTIPID=$!
20020         # remove the files & current working dir
20021         unlinkmany $DIR/$tdir/foobar 4000
20022         rmdir $DIR/$tdir
20023         kill -USR1 $MULTIPID
20024         wait $MULTIPID
20025         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
20026         return 0
20027 }
20028 run_test 181 "Test open-unlinked dir ========================"
20029
20030 test_182a() {
20031         local fcount=1000
20032         local tcount=10
20033
20034         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20035
20036         $LCTL set_param mdc.*.rpc_stats=clear
20037
20038         for (( i = 0; i < $tcount; i++ )) ; do
20039                 mkdir $DIR/$tdir/$i
20040         done
20041
20042         for (( i = 0; i < $tcount; i++ )) ; do
20043                 createmany -o $DIR/$tdir/$i/f- $fcount &
20044         done
20045         wait
20046
20047         for (( i = 0; i < $tcount; i++ )) ; do
20048                 unlinkmany $DIR/$tdir/$i/f- $fcount &
20049         done
20050         wait
20051
20052         $LCTL get_param mdc.*.rpc_stats
20053
20054         rm -rf $DIR/$tdir
20055 }
20056 run_test 182a "Test parallel modify metadata operations from mdc"
20057
20058 test_182b() {
20059         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20060         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20061         local dcount=1000
20062         local tcount=10
20063         local stime
20064         local etime
20065         local delta
20066
20067         do_facet mds1 $LCTL list_param \
20068                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
20069                 skip "MDS lacks parallel RPC handling"
20070
20071         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20072
20073         rpc_count=$(do_facet mds1 $LCTL get_param -n \
20074                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
20075
20076         stime=$(date +%s)
20077         createmany -i 0 -d $DIR/$tdir/t- $tcount
20078
20079         for (( i = 0; i < $tcount; i++ )) ; do
20080                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20081         done
20082         wait
20083         etime=$(date +%s)
20084         delta=$((etime - stime))
20085         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
20086
20087         stime=$(date +%s)
20088         for (( i = 0; i < $tcount; i++ )) ; do
20089                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
20090         done
20091         wait
20092         etime=$(date +%s)
20093         delta=$((etime - stime))
20094         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
20095
20096         rm -rf $DIR/$tdir
20097
20098         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20099
20100         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
20101
20102         stime=$(date +%s)
20103         createmany -i 0 -d $DIR/$tdir/t- $tcount
20104
20105         for (( i = 0; i < $tcount; i++ )) ; do
20106                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20107         done
20108         wait
20109         etime=$(date +%s)
20110         delta=$((etime - stime))
20111         echo "Time for file creation $delta sec for 1 RPC sent at a time"
20112
20113         stime=$(date +%s)
20114         for (( i = 0; i < $tcount; i++ )) ; do
20115                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
20116         done
20117         wait
20118         etime=$(date +%s)
20119         delta=$((etime - stime))
20120         echo "Time for file removal $delta sec for 1 RPC sent at a time"
20121
20122         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
20123 }
20124 run_test 182b "Test parallel modify metadata operations from osp"
20125
20126 test_183() { # LU-2275
20127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20128         remote_mds_nodsh && skip "remote MDS with nodsh"
20129         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
20130                 skip "Need MDS version at least 2.3.56"
20131
20132         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20133         echo aaa > $DIR/$tdir/$tfile
20134
20135 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
20136         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
20137
20138         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
20139         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
20140
20141         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20142
20143         # Flush negative dentry cache
20144         touch $DIR/$tdir/$tfile
20145
20146         # We are not checking for any leaked references here, they'll
20147         # become evident next time we do cleanup with module unload.
20148         rm -rf $DIR/$tdir
20149 }
20150 run_test 183 "No crash or request leak in case of strange dispositions ========"
20151
20152 # test suite 184 is for LU-2016, LU-2017
20153 test_184a() {
20154         check_swap_layouts_support
20155
20156         dir0=$DIR/$tdir/$testnum
20157         test_mkdir -p -c1 $dir0
20158         ref1=/etc/passwd
20159         ref2=/etc/group
20160         file1=$dir0/f1
20161         file2=$dir0/f2
20162         $LFS setstripe -c1 $file1
20163         cp $ref1 $file1
20164         $LFS setstripe -c2 $file2
20165         cp $ref2 $file2
20166         gen1=$($LFS getstripe -g $file1)
20167         gen2=$($LFS getstripe -g $file2)
20168
20169         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20170         gen=$($LFS getstripe -g $file1)
20171         [[ $gen1 != $gen ]] ||
20172                 error "Layout generation on $file1 does not change"
20173         gen=$($LFS getstripe -g $file2)
20174         [[ $gen2 != $gen ]] ||
20175                 error "Layout generation on $file2 does not change"
20176
20177         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20178         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20179
20180         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20181 }
20182 run_test 184a "Basic layout swap"
20183
20184 test_184b() {
20185         check_swap_layouts_support
20186
20187         dir0=$DIR/$tdir/$testnum
20188         mkdir -p $dir0 || error "creating dir $dir0"
20189         file1=$dir0/f1
20190         file2=$dir0/f2
20191         file3=$dir0/f3
20192         dir1=$dir0/d1
20193         dir2=$dir0/d2
20194         mkdir $dir1 $dir2
20195         $LFS setstripe -c1 $file1
20196         $LFS setstripe -c2 $file2
20197         $LFS setstripe -c1 $file3
20198         chown $RUNAS_ID $file3
20199         gen1=$($LFS getstripe -g $file1)
20200         gen2=$($LFS getstripe -g $file2)
20201
20202         $LFS swap_layouts $dir1 $dir2 &&
20203                 error "swap of directories layouts should fail"
20204         $LFS swap_layouts $dir1 $file1 &&
20205                 error "swap of directory and file layouts should fail"
20206         $RUNAS $LFS swap_layouts $file1 $file2 &&
20207                 error "swap of file we cannot write should fail"
20208         $LFS swap_layouts $file1 $file3 &&
20209                 error "swap of file with different owner should fail"
20210         /bin/true # to clear error code
20211 }
20212 run_test 184b "Forbidden layout swap (will generate errors)"
20213
20214 test_184c() {
20215         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20216         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20217         check_swap_layouts_support
20218         check_swap_layout_no_dom $DIR
20219
20220         local dir0=$DIR/$tdir/$testnum
20221         mkdir -p $dir0 || error "creating dir $dir0"
20222
20223         local ref1=$dir0/ref1
20224         local ref2=$dir0/ref2
20225         local file1=$dir0/file1
20226         local file2=$dir0/file2
20227         # create a file large enough for the concurrent test
20228         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20229         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20230         echo "ref file size: ref1($(stat -c %s $ref1))," \
20231              "ref2($(stat -c %s $ref2))"
20232
20233         cp $ref2 $file2
20234         dd if=$ref1 of=$file1 bs=16k &
20235         local DD_PID=$!
20236
20237         # Make sure dd starts to copy file, but wait at most 5 seconds
20238         local loops=0
20239         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20240
20241         $LFS swap_layouts $file1 $file2
20242         local rc=$?
20243         wait $DD_PID
20244         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20245         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20246
20247         # how many bytes copied before swapping layout
20248         local copied=$(stat -c %s $file2)
20249         local remaining=$(stat -c %s $ref1)
20250         remaining=$((remaining - copied))
20251         echo "Copied $copied bytes before swapping layout..."
20252
20253         cmp -n $copied $file1 $ref2 | grep differ &&
20254                 error "Content mismatch [0, $copied) of ref2 and file1"
20255         cmp -n $copied $file2 $ref1 ||
20256                 error "Content mismatch [0, $copied) of ref1 and file2"
20257         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20258                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20259
20260         # clean up
20261         rm -f $ref1 $ref2 $file1 $file2
20262 }
20263 run_test 184c "Concurrent write and layout swap"
20264
20265 test_184d() {
20266         check_swap_layouts_support
20267         check_swap_layout_no_dom $DIR
20268         [ -z "$(which getfattr 2>/dev/null)" ] &&
20269                 skip_env "no getfattr command"
20270
20271         local file1=$DIR/$tdir/$tfile-1
20272         local file2=$DIR/$tdir/$tfile-2
20273         local file3=$DIR/$tdir/$tfile-3
20274         local lovea1
20275         local lovea2
20276
20277         mkdir -p $DIR/$tdir
20278         touch $file1 || error "create $file1 failed"
20279         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20280                 error "create $file2 failed"
20281         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20282                 error "create $file3 failed"
20283         lovea1=$(get_layout_param $file1)
20284
20285         $LFS swap_layouts $file2 $file3 ||
20286                 error "swap $file2 $file3 layouts failed"
20287         $LFS swap_layouts $file1 $file2 ||
20288                 error "swap $file1 $file2 layouts failed"
20289
20290         lovea2=$(get_layout_param $file2)
20291         echo "$lovea1"
20292         echo "$lovea2"
20293         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20294
20295         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20296         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20297 }
20298 run_test 184d "allow stripeless layouts swap"
20299
20300 test_184e() {
20301         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20302                 skip "Need MDS version at least 2.6.94"
20303         check_swap_layouts_support
20304         check_swap_layout_no_dom $DIR
20305         [ -z "$(which getfattr 2>/dev/null)" ] &&
20306                 skip_env "no getfattr command"
20307
20308         local file1=$DIR/$tdir/$tfile-1
20309         local file2=$DIR/$tdir/$tfile-2
20310         local file3=$DIR/$tdir/$tfile-3
20311         local lovea
20312
20313         mkdir -p $DIR/$tdir
20314         touch $file1 || error "create $file1 failed"
20315         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20316                 error "create $file2 failed"
20317         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20318                 error "create $file3 failed"
20319
20320         $LFS swap_layouts $file1 $file2 ||
20321                 error "swap $file1 $file2 layouts failed"
20322
20323         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20324         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20325
20326         echo 123 > $file1 || error "Should be able to write into $file1"
20327
20328         $LFS swap_layouts $file1 $file3 ||
20329                 error "swap $file1 $file3 layouts failed"
20330
20331         echo 123 > $file1 || error "Should be able to write into $file1"
20332
20333         rm -rf $file1 $file2 $file3
20334 }
20335 run_test 184e "Recreate layout after stripeless layout swaps"
20336
20337 test_184f() {
20338         # Create a file with name longer than sizeof(struct stat) ==
20339         # 144 to see if we can get chars from the file name to appear
20340         # in the returned striping. Note that 'f' == 0x66.
20341         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20342
20343         mkdir -p $DIR/$tdir
20344         mcreate $DIR/$tdir/$file
20345         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20346                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20347         fi
20348 }
20349 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20350
20351 test_185() { # LU-2441
20352         # LU-3553 - no volatile file support in old servers
20353         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20354                 skip "Need MDS version at least 2.3.60"
20355
20356         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20357         touch $DIR/$tdir/spoo
20358         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20359         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20360                 error "cannot create/write a volatile file"
20361         [ "$FILESET" == "" ] &&
20362         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20363                 error "FID is still valid after close"
20364
20365         multiop_bg_pause $DIR/$tdir Vw4096_c
20366         local multi_pid=$!
20367
20368         local OLD_IFS=$IFS
20369         IFS=":"
20370         local fidv=($fid)
20371         IFS=$OLD_IFS
20372         # assume that the next FID for this client is sequential, since stdout
20373         # is unfortunately eaten by multiop_bg_pause
20374         local n=$((${fidv[1]} + 1))
20375         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20376         if [ "$FILESET" == "" ]; then
20377                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20378                         error "FID is missing before close"
20379         fi
20380         kill -USR1 $multi_pid
20381         # 1 second delay, so if mtime change we will see it
20382         sleep 1
20383         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20384         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20385 }
20386 run_test 185 "Volatile file support"
20387
20388 function create_check_volatile() {
20389         local idx=$1
20390         local tgt
20391
20392         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20393         local PID=$!
20394         sleep 1
20395         local FID=$(cat /tmp/${tfile}.fid)
20396         [ "$FID" == "" ] && error "can't get FID for volatile"
20397         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20398         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20399         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20400         kill -USR1 $PID
20401         wait
20402         sleep 1
20403         cancel_lru_locks mdc # flush opencache
20404         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20405         return 0
20406 }
20407
20408 test_185a(){
20409         # LU-12516 - volatile creation via .lustre
20410         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20411                 skip "Need MDS version at least 2.3.55"
20412
20413         create_check_volatile 0
20414         [ $MDSCOUNT -lt 2 ] && return 0
20415
20416         # DNE case
20417         create_check_volatile 1
20418
20419         return 0
20420 }
20421 run_test 185a "Volatile file creation in .lustre/fid/"
20422
20423 test_187a() {
20424         remote_mds_nodsh && skip "remote MDS with nodsh"
20425         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20426                 skip "Need MDS version at least 2.3.0"
20427
20428         local dir0=$DIR/$tdir/$testnum
20429         mkdir -p $dir0 || error "creating dir $dir0"
20430
20431         local file=$dir0/file1
20432         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20433         stack_trap "rm -f $file"
20434         local dv1=$($LFS data_version $file)
20435         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20436         local dv2=$($LFS data_version $file)
20437         [[ $dv1 != $dv2 ]] ||
20438                 error "data version did not change on write $dv1 == $dv2"
20439 }
20440 run_test 187a "Test data version change"
20441
20442 test_187b() {
20443         remote_mds_nodsh && skip "remote MDS with nodsh"
20444         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20445                 skip "Need MDS version at least 2.3.0"
20446
20447         local dir0=$DIR/$tdir/$testnum
20448         mkdir -p $dir0 || error "creating dir $dir0"
20449
20450         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20451         [[ ${DV[0]} != ${DV[1]} ]] ||
20452                 error "data version did not change on write"\
20453                       " ${DV[0]} == ${DV[1]}"
20454
20455         # clean up
20456         rm -f $file1
20457 }
20458 run_test 187b "Test data version change on volatile file"
20459
20460 test_200() {
20461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20462         remote_mgs_nodsh && skip "remote MGS with nodsh"
20463         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20464
20465         local POOL=${POOL:-cea1}
20466         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20467         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20468         # Pool OST targets
20469         local first_ost=0
20470         local last_ost=$(($OSTCOUNT - 1))
20471         local ost_step=2
20472         local ost_list=$(seq $first_ost $ost_step $last_ost)
20473         local ost_range="$first_ost $last_ost $ost_step"
20474         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20475         local file_dir=$POOL_ROOT/file_tst
20476         local subdir=$test_path/subdir
20477         local rc=0
20478
20479         while : ; do
20480                 # former test_200a test_200b
20481                 pool_add $POOL                          || { rc=$? ; break; }
20482                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20483                 # former test_200c test_200d
20484                 mkdir -p $test_path
20485                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20486                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20487                 mkdir -p $subdir
20488                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20489                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20490                                                         || { rc=$? ; break; }
20491                 # former test_200e test_200f
20492                 local files=$((OSTCOUNT*3))
20493                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20494                                                         || { rc=$? ; break; }
20495                 pool_create_files $POOL $file_dir $files "$ost_list" \
20496                                                         || { rc=$? ; break; }
20497                 # former test_200g test_200h
20498                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20499                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20500
20501                 # former test_201a test_201b test_201c
20502                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20503
20504                 local f=$test_path/$tfile
20505                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20506                 pool_remove $POOL $f                    || { rc=$? ; break; }
20507                 break
20508         done
20509
20510         destroy_test_pools
20511
20512         return $rc
20513 }
20514 run_test 200 "OST pools"
20515
20516 # usage: default_attr <count | size | offset>
20517 default_attr() {
20518         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20519 }
20520
20521 # usage: check_default_stripe_attr
20522 check_default_stripe_attr() {
20523         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20524         case $1 in
20525         --stripe-count|-c)
20526                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20527         --stripe-size|-S)
20528                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20529         --stripe-index|-i)
20530                 EXPECTED=-1;;
20531         *)
20532                 error "unknown getstripe attr '$1'"
20533         esac
20534
20535         [ $ACTUAL == $EXPECTED ] ||
20536                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20537 }
20538
20539 test_204a() {
20540         test_mkdir $DIR/$tdir
20541         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20542
20543         check_default_stripe_attr --stripe-count
20544         check_default_stripe_attr --stripe-size
20545         check_default_stripe_attr --stripe-index
20546 }
20547 run_test 204a "Print default stripe attributes"
20548
20549 test_204b() {
20550         test_mkdir $DIR/$tdir
20551         $LFS setstripe --stripe-count 1 $DIR/$tdir
20552
20553         check_default_stripe_attr --stripe-size
20554         check_default_stripe_attr --stripe-index
20555 }
20556 run_test 204b "Print default stripe size and offset"
20557
20558 test_204c() {
20559         test_mkdir $DIR/$tdir
20560         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20561
20562         check_default_stripe_attr --stripe-count
20563         check_default_stripe_attr --stripe-index
20564 }
20565 run_test 204c "Print default stripe count and offset"
20566
20567 test_204d() {
20568         test_mkdir $DIR/$tdir
20569         $LFS setstripe --stripe-index 0 $DIR/$tdir
20570
20571         check_default_stripe_attr --stripe-count
20572         check_default_stripe_attr --stripe-size
20573 }
20574 run_test 204d "Print default stripe count and size"
20575
20576 test_204e() {
20577         test_mkdir $DIR/$tdir
20578         $LFS setstripe -d $DIR/$tdir
20579
20580         # LU-16904 check if root is set as PFL layout
20581         local numcomp=$($LFS getstripe --component-count $MOUNT)
20582
20583         if [[ $numcomp -gt 0 ]]; then
20584                 check_default_stripe_attr --stripe-count
20585         else
20586                 check_default_stripe_attr --stripe-count --raw
20587         fi
20588         check_default_stripe_attr --stripe-size --raw
20589         check_default_stripe_attr --stripe-index --raw
20590 }
20591 run_test 204e "Print raw stripe attributes"
20592
20593 test_204f() {
20594         test_mkdir $DIR/$tdir
20595         $LFS setstripe --stripe-count 1 $DIR/$tdir
20596
20597         check_default_stripe_attr --stripe-size --raw
20598         check_default_stripe_attr --stripe-index --raw
20599 }
20600 run_test 204f "Print raw stripe size and offset"
20601
20602 test_204g() {
20603         test_mkdir $DIR/$tdir
20604         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20605
20606         check_default_stripe_attr --stripe-count --raw
20607         check_default_stripe_attr --stripe-index --raw
20608 }
20609 run_test 204g "Print raw stripe count and offset"
20610
20611 test_204h() {
20612         test_mkdir $DIR/$tdir
20613         $LFS setstripe --stripe-index 0 $DIR/$tdir
20614
20615         check_default_stripe_attr --stripe-count --raw
20616         check_default_stripe_attr --stripe-size --raw
20617 }
20618 run_test 204h "Print raw stripe count and size"
20619
20620 # Figure out which job scheduler is being used, if any,
20621 # or use a fake one
20622 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20623         JOBENV=SLURM_JOB_ID
20624 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20625         JOBENV=LSB_JOBID
20626 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20627         JOBENV=PBS_JOBID
20628 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20629         JOBENV=LOADL_STEP_ID
20630 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20631         JOBENV=JOB_ID
20632 else
20633         $LCTL list_param jobid_name > /dev/null 2>&1
20634         if [ $? -eq 0 ]; then
20635                 JOBENV=nodelocal
20636         else
20637                 JOBENV=FAKE_JOBID
20638         fi
20639 fi
20640 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20641
20642 verify_jobstats() {
20643         local cmd=($1)
20644         shift
20645         local facets="$@"
20646
20647 # we don't really need to clear the stats for this test to work, since each
20648 # command has a unique jobid, but it makes debugging easier if needed.
20649 #       for facet in $facets; do
20650 #               local dev=$(convert_facet2label $facet)
20651 #               # clear old jobstats
20652 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20653 #       done
20654
20655         # use a new JobID for each test, or we might see an old one
20656         [ "$JOBENV" = "FAKE_JOBID" ] &&
20657                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20658
20659         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20660
20661         [ "$JOBENV" = "nodelocal" ] && {
20662                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20663                 $LCTL set_param jobid_name=$FAKE_JOBID
20664                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20665         }
20666
20667         log "Test: ${cmd[*]}"
20668         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20669
20670         if [ $JOBENV = "FAKE_JOBID" ]; then
20671                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20672         else
20673                 ${cmd[*]}
20674         fi
20675
20676         # all files are created on OST0000
20677         for facet in $facets; do
20678                 local stats="*.$(convert_facet2label $facet).job_stats"
20679
20680                 # strip out libtool wrappers for in-tree executables
20681                 if (( $(do_facet $facet lctl get_param $stats |
20682                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20683                         do_facet $facet lctl get_param $stats
20684                         error "No jobstats for $JOBVAL found on $facet::$stats"
20685                 fi
20686         done
20687 }
20688
20689 jobstats_set() {
20690         local new_jobenv=$1
20691
20692         set_persistent_param_and_check client "jobid_var" \
20693                 "$FSNAME.sys.jobid_var" $new_jobenv
20694 }
20695
20696 test_205a() { # Job stats
20697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20698         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20699                 skip "Need MDS version with at least 2.7.1"
20700         remote_mgs_nodsh && skip "remote MGS with nodsh"
20701         remote_mds_nodsh && skip "remote MDS with nodsh"
20702         remote_ost_nodsh && skip "remote OST with nodsh"
20703         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20704                 skip "Server doesn't support jobstats"
20705         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20706
20707         local old_jobenv=$($LCTL get_param -n jobid_var)
20708         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20709         stack_trap "jobstats_set $old_jobenv" EXIT
20710
20711         changelog_register
20712
20713         local old_jobid_name=$($LCTL get_param jobid_name)
20714         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20715
20716         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20717                                 mdt.*.job_cleanup_interval | head -n 1)
20718         local new_interval=5
20719         do_facet $SINGLEMDS \
20720                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20721         stack_trap "do_facet $SINGLEMDS \
20722                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20723         local start=$SECONDS
20724
20725         local cmd
20726         # mkdir
20727         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20728         verify_jobstats "$cmd" "$SINGLEMDS"
20729         # rmdir
20730         cmd="rmdir $DIR/$tdir"
20731         verify_jobstats "$cmd" "$SINGLEMDS"
20732         # mkdir on secondary MDT
20733         if [ $MDSCOUNT -gt 1 ]; then
20734                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20735                 verify_jobstats "$cmd" "mds2"
20736         fi
20737         # mknod
20738         cmd="mknod $DIR/$tfile c 1 3"
20739         verify_jobstats "$cmd" "$SINGLEMDS"
20740         # unlink
20741         cmd="rm -f $DIR/$tfile"
20742         verify_jobstats "$cmd" "$SINGLEMDS"
20743         # create all files on OST0000 so verify_jobstats can find OST stats
20744         # open & close
20745         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20746         verify_jobstats "$cmd" "$SINGLEMDS"
20747         # setattr
20748         cmd="touch $DIR/$tfile"
20749         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20750         # write
20751         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20752         verify_jobstats "$cmd" "ost1"
20753         # read
20754         cancel_lru_locks osc
20755         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20756         verify_jobstats "$cmd" "ost1"
20757         # truncate
20758         cmd="$TRUNCATE $DIR/$tfile 0"
20759         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20760         # rename
20761         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20762         verify_jobstats "$cmd" "$SINGLEMDS"
20763         # jobstats expiry - sleep until old stats should be expired
20764         local left=$((new_interval + 5 - (SECONDS - start)))
20765         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20766                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20767                         "0" $left
20768         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20769         verify_jobstats "$cmd" "$SINGLEMDS"
20770         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20771             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20772
20773         # Ensure that jobid are present in changelog (if supported by MDS)
20774         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20775                 changelog_dump | tail -10
20776                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20777                 [ $jobids -eq 9 ] ||
20778                         error "Wrong changelog jobid count $jobids != 9"
20779
20780                 # LU-5862
20781                 JOBENV="disable"
20782                 jobstats_set $JOBENV
20783                 touch $DIR/$tfile
20784                 changelog_dump | grep $tfile
20785                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20786                 [ $jobids -eq 0 ] ||
20787                         error "Unexpected jobids when jobid_var=$JOBENV"
20788         fi
20789
20790         # test '%j' access to environment variable - if supported
20791         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20792                 JOBENV="JOBCOMPLEX"
20793                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20794
20795                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20796         fi
20797
20798         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20799                 JOBENV="JOBCOMPLEX"
20800                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20801
20802                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20803         fi
20804
20805         # test '%j' access to per-session jobid - if supported
20806         if lctl list_param jobid_this_session > /dev/null 2>&1
20807         then
20808                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20809                 lctl set_param jobid_this_session=$USER
20810
20811                 JOBENV="JOBCOMPLEX"
20812                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20813
20814                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20815         fi
20816 }
20817 run_test 205a "Verify job stats"
20818
20819 # LU-13117, LU-13597, LU-16599
20820 test_205b() {
20821         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20822                 skip "Need MDS version at least 2.13.54.91"
20823
20824         local job_stats="mdt.*.job_stats"
20825         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20826
20827         do_facet mds1 $LCTL set_param $job_stats=clear
20828
20829         # Setting jobid_var to USER might not be supported
20830         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20831         $LCTL set_param jobid_var=USER || true
20832         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20833         $LCTL set_param jobid_name="%j.%e.%u"
20834
20835         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20836         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20837                 { do_facet mds1 $LCTL get_param $job_stats;
20838                   error "Unexpected jobid found"; }
20839         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20840                 { do_facet mds1 $LCTL get_param $job_stats;
20841                   error "wrong job_stats format found"; }
20842
20843         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20844                 echo "MDS does not yet escape jobid" && return 0
20845
20846         mkdir_on_mdt0 $DIR/$tdir
20847         $LCTL set_param jobid_var=TEST205b
20848         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20849         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20850                       awk '/has\\x20sp/ {print $3}')
20851         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20852                   error "jobid not escaped"; }
20853
20854         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20855                 # need to run such a command on mds1:
20856                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20857                 #
20858                 # there might be multiple MDTs on single mds server, so need to
20859                 # specifiy MDT0000. Or the command will fail due to other MDTs
20860                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20861                         error "cannot clear escaped jobid in job_stats";
20862         else
20863                 echo "MDS does not support clearing escaped jobid"
20864         fi
20865 }
20866 run_test 205b "Verify job stats jobid and output format"
20867
20868 # LU-13733
20869 test_205c() {
20870         $LCTL set_param llite.*.stats=0
20871         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20872         $LCTL get_param llite.*.stats
20873         $LCTL get_param llite.*.stats | grep \
20874                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20875                         error "wrong client stats format found"
20876 }
20877 run_test 205c "Verify client stats format"
20878
20879 test_205d() {
20880         local file=$DIR/$tdir/$tfile
20881
20882         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20883                 skip "need lustre >= 2.15.53 for lljobstat"
20884         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20885                 skip "need lustre >= 2.15.53 for lljobstat"
20886         verify_yaml_available || skip_env "YAML verification not installed"
20887
20888         test_mkdir -i 0 $DIR/$tdir
20889         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20890         stack_trap "rm -rf $DIR/$tdir"
20891
20892         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20893                 error "failed to write data to $file"
20894         mv $file $file.2
20895
20896         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20897         echo -n 'verify rename_stats...'
20898         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20899                 verify_yaml || error "rename_stats is not valid YAML"
20900         echo " OK"
20901
20902         echo -n 'verify mdt job_stats...'
20903         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20904                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20905         echo " OK"
20906
20907         echo -n 'verify ost job_stats...'
20908         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20909                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20910         echo " OK"
20911 }
20912 run_test 205d "verify the format of some stats files"
20913
20914 test_205e() {
20915         local ops_comma
20916         local file=$DIR/$tdir/$tfile
20917         local -a cli_params
20918
20919         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20920                 skip "need lustre >= 2.15.53 for lljobstat"
20921         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20922                 skip "need lustre >= 2.15.53 for lljobstat"
20923         verify_yaml_available || skip_env "YAML verification not installed"
20924
20925         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20926         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20927         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20928
20929         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20930         stack_trap "rm -rf $DIR/$tdir"
20931
20932         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20933                 error "failed to create $file on ost1"
20934         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20935                 error "failed to write data to $file"
20936
20937         do_facet mds1 "$LCTL get_param *.*.job_stats"
20938         do_facet ost1 "$LCTL get_param *.*.job_stats"
20939
20940         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20941         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20942                 error "The output of lljobstat is not an valid YAML"
20943
20944         # verify that job dd.0 does exist and has some ops on ost1
20945         # typically this line is like:
20946         # - 205e.dd.0:            {ops: 20, ...}
20947         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20948                     awk '$2=="205e.dd.0:" {print $4}')
20949
20950         (( ${ops_comma%,} >= 10 )) ||
20951                 error "cannot find job 205e.dd.0 with ops >= 10"
20952 }
20953 run_test 205e "verify the output of lljobstat"
20954
20955 test_205f() {
20956         verify_yaml_available || skip_env "YAML verification not installed"
20957
20958         # check both qos_ost_weights and qos_mdt_weights
20959         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20960         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20961                 error "qos_ost_weights is not valid YAML"
20962 }
20963 run_test 205f "verify qos_ost_weights YAML format "
20964
20965 __test_205_jobstats_dump() {
20966         local -a pids
20967         local nbr_instance=$1
20968
20969         while true; do
20970                 if (( ${#pids[@]} >= nbr_instance )); then
20971                         wait ${pids[@]}
20972                         pids=()
20973                 fi
20974
20975                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20976                 pids+=( $! )
20977         done
20978 }
20979
20980 __test_205_cleanup() {
20981         kill $@
20982         # Clear all job entries
20983         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20984 }
20985
20986 test_205g() {
20987         local -a mds1_params
20988         local -a cli_params
20989         local pids
20990         local interval=5
20991
20992         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20993         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20994         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20995
20996         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20997         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20998         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20999
21000         # start jobs loop
21001         export TEST205G_ID=205g
21002         stack_trap "unset TEST205G_ID" EXIT
21003         while true; do
21004                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
21005         done & pids="$! "
21006
21007         __test_205_jobstats_dump 4 & pids+="$! "
21008         stack_trap "__test_205_cleanup $pids" EXIT INT
21009
21010         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
21011 }
21012 run_test 205g "stress test for job_stats procfile"
21013
21014 test_205h() {
21015         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
21016                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
21017         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
21018
21019         local dir=$DIR/$tdir
21020         local f=$dir/$tfile
21021         local f2=$dir/$tfile-2
21022         local f3=$dir/$tfile-3
21023         local subdir=$DIR/dir
21024         local val
21025
21026         local mdts=$(comma_list $(mdts_nodes))
21027         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
21028         local client_saved=$($LCTL get_param -n jobid_var)
21029
21030         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
21031         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
21032
21033         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
21034                 error "failed to set job_xattr parameter to user.job"
21035         $LCTL set_param jobid_var=procname.uid ||
21036                 error "failed to set jobid_var parameter"
21037
21038         test_mkdir $dir
21039
21040         touch $f
21041         val=$(getfattr -n user.job $f | grep user.job)
21042         [[ $val = user.job=\"touch.0\" ]] ||
21043                 error "expected user.job=\"touch.0\", got '$val'"
21044
21045         mkdir $subdir
21046         val=$(getfattr -n user.job $subdir | grep user.job)
21047         [[ $val = user.job=\"mkdir.0\" ]] ||
21048                 error "expected user.job=\"mkdir.0\", got '$val'"
21049
21050         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
21051                 error "failed to set job_xattr parameter to NONE"
21052
21053         touch $f2
21054         val=$(getfattr -d $f2)
21055         [[ -z $val ]] ||
21056                 error "expected no user xattr, got '$val'"
21057
21058         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
21059                 error "failed to set job_xattr parameter to trusted.job"
21060
21061         touch $f3
21062         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
21063         [[ $val = trusted.job=\"touch.0\" ]] ||
21064                 error "expected trusted.job=\"touch.0\", got '$val'"
21065 }
21066 run_test 205h "check jobid xattr is stored correctly"
21067
21068 test_205i() {
21069         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
21070                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
21071
21072         local mdts=$(comma_list $(mdts_nodes))
21073         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
21074
21075         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
21076
21077         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
21078                 error "failed to set mdt.*.job_xattr to user.1234567"
21079
21080         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
21081                 error "failed to reject too long job_xattr name"
21082
21083         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
21084                 error "failed to reject job_xattr name in bad format"
21085
21086         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
21087                 error "failed to reject job_xattr name with invalid character"
21088
21089         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
21090                         xargs $LCTL set_param" &&
21091                 error "failed to reject job_xattr name with non-ascii character"
21092
21093         return 0
21094 }
21095 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
21096
21097 # LU-1480, LU-1773 and LU-1657
21098 test_206() {
21099         mkdir -p $DIR/$tdir
21100         $LFS setstripe -c -1 $DIR/$tdir
21101 #define OBD_FAIL_LOV_INIT 0x1403
21102         $LCTL set_param fail_loc=0xa0001403
21103         $LCTL set_param fail_val=1
21104         touch $DIR/$tdir/$tfile || true
21105 }
21106 run_test 206 "fail lov_init_raid0() doesn't lbug"
21107
21108 test_207a() {
21109         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21110         local fsz=`stat -c %s $DIR/$tfile`
21111         cancel_lru_locks mdc
21112
21113         # do not return layout in getattr intent
21114 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
21115         $LCTL set_param fail_loc=0x170
21116         local sz=`stat -c %s $DIR/$tfile`
21117
21118         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
21119
21120         rm -rf $DIR/$tfile
21121 }
21122 run_test 207a "can refresh layout at glimpse"
21123
21124 test_207b() {
21125         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21126         local cksum=`md5sum $DIR/$tfile`
21127         local fsz=`stat -c %s $DIR/$tfile`
21128         cancel_lru_locks mdc
21129         cancel_lru_locks osc
21130
21131         # do not return layout in getattr intent
21132 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
21133         $LCTL set_param fail_loc=0x171
21134
21135         # it will refresh layout after the file is opened but before read issues
21136         echo checksum is "$cksum"
21137         echo "$cksum" |md5sum -c --quiet || error "file differs"
21138
21139         rm -rf $DIR/$tfile
21140 }
21141 run_test 207b "can refresh layout at open"
21142
21143 test_208() {
21144         # FIXME: in this test suite, only RD lease is used. This is okay
21145         # for now as only exclusive open is supported. After generic lease
21146         # is done, this test suite should be revised. - Jinshan
21147
21148         remote_mds_nodsh && skip "remote MDS with nodsh"
21149         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21150                 skip "Need MDS version at least 2.4.52"
21151
21152         echo "==== test 1: verify get lease work"
21153         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21154
21155         echo "==== test 2: verify lease can be broken by upcoming open"
21156         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21157         local PID=$!
21158         sleep 2
21159
21160         $MULTIOP $DIR/$tfile oO_RDWR:c
21161         kill -USR1 $PID && wait $PID || error "break lease error"
21162
21163         echo "==== test 3: verify lease can't be granted if an open already exists"
21164         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21165         local PID=$!
21166         sleep 2
21167
21168         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21169         kill -USR1 $PID && wait $PID || error "open file error"
21170
21171         echo "==== test 4: lease can sustain over recovery"
21172         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21173         PID=$!
21174         sleep 2
21175
21176         fail mds1
21177
21178         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21179
21180         echo "==== test 5: lease broken can't be regained by replay"
21181         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21182         PID=$!
21183         sleep 2
21184
21185         # open file to break lease and then recovery
21186         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21187         fail mds1
21188
21189         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21190
21191         rm -f $DIR/$tfile
21192 }
21193 run_test 208 "Exclusive open"
21194
21195 test_209() {
21196         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21197                 skip_env "must have disp_stripe"
21198
21199         touch $DIR/$tfile
21200         sync; sleep 5; sync;
21201
21202         echo 3 > /proc/sys/vm/drop_caches
21203         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21204                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21205         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21206
21207         # open/close 500 times
21208         for i in $(seq 500); do
21209                 cat $DIR/$tfile
21210         done
21211
21212         echo 3 > /proc/sys/vm/drop_caches
21213         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21214                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21215         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21216
21217         echo "before: $req_before, after: $req_after"
21218         [ $((req_after - req_before)) -ge 300 ] &&
21219                 error "open/close requests are not freed"
21220         return 0
21221 }
21222 run_test 209 "read-only open/close requests should be freed promptly"
21223
21224 test_210() {
21225         local pid
21226
21227         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21228         pid=$!
21229         sleep 1
21230
21231         $LFS getstripe $DIR/$tfile
21232         kill -USR1 $pid
21233         wait $pid || error "multiop failed"
21234
21235         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21236         pid=$!
21237         sleep 1
21238
21239         $LFS getstripe $DIR/$tfile
21240         kill -USR1 $pid
21241         wait $pid || error "multiop failed"
21242 }
21243 run_test 210 "lfs getstripe does not break leases"
21244
21245 function test_211() {
21246         local PID
21247         local id
21248         local rc
21249
21250         stack_trap "rm -f $DIR/$tfile" EXIT
21251         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21252                 error "can't create file"
21253         $LFS mirror extend -N $DIR/$tfile ||
21254                 error "can't create a replica"
21255         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21256         $LFS getstripe $DIR/$tfile
21257         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21258         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21259
21260         $MULTIOP $DIR/$tfile OeW_E+eUc &
21261         PID=$!
21262         sleep 0.3
21263
21264         id=$($LFS getstripe $DIR/$tfile |
21265                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21266         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21267                 error "removed last in-sync replica?"
21268
21269         kill -USR1 $PID
21270         wait $PID
21271         (( $? == 0 )) || error "failed split broke the lease"
21272 }
21273 run_test 211 "failed mirror split doesn't break write lease"
21274
21275 test_212() {
21276         size=`date +%s`
21277         size=$((size % 8192 + 1))
21278         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21279         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21280         rm -f $DIR/f212 $DIR/f212.xyz
21281 }
21282 run_test 212 "Sendfile test ============================================"
21283
21284 test_213() {
21285         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21286         cancel_lru_locks osc
21287         lctl set_param fail_loc=0x8000040f
21288         # generate a read lock
21289         cat $DIR/$tfile > /dev/null
21290         # write to the file, it will try to cancel the above read lock.
21291         cat /etc/hosts >> $DIR/$tfile
21292 }
21293 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21294
21295 test_214() { # for bug 20133
21296         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21297         for (( i=0; i < 340; i++ )) ; do
21298                 touch $DIR/$tdir/d214c/a$i
21299         done
21300
21301         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21302         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21303         ls $DIR/d214c || error "ls $DIR/d214c failed"
21304         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21305         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21306 }
21307 run_test 214 "hash-indexed directory test - bug 20133"
21308
21309 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21310 create_lnet_proc_files() {
21311         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21312 }
21313
21314 # counterpart of create_lnet_proc_files
21315 remove_lnet_proc_files() {
21316         rm -f $TMP/lnet_$1.sys
21317 }
21318
21319 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21320 # 3rd arg as regexp for body
21321 check_lnet_proc_stats() {
21322         local l=$(cat "$TMP/lnet_$1" |wc -l)
21323         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21324
21325         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21326 }
21327
21328 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21329 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21330 # optional and can be regexp for 2nd line (lnet.routes case)
21331 check_lnet_proc_entry() {
21332         local blp=2          # blp stands for 'position of 1st line of body'
21333         [ -z "$5" ] || blp=3 # lnet.routes case
21334
21335         local l=$(cat "$TMP/lnet_$1" |wc -l)
21336         # subtracting one from $blp because the body can be empty
21337         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21338
21339         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21340                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21341
21342         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21343                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21344
21345         # bail out if any unexpected line happened
21346         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21347         [ "$?" != 0 ] || error "$2 misformatted"
21348 }
21349
21350 test_215() { # for bugs 18102, 21079, 21517
21351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21352
21353         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21354         local P='[1-9][0-9]*'           # positive numeric
21355         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21356         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21357         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21358         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21359         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21360         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21361
21362         local L1 # regexp for 1st line
21363         local L2 # regexp for 2nd line (optional)
21364         local BR # regexp for the rest (body)
21365
21366         # lnet.stats should look as 11 space-separated non-negative numerics
21367         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21368         create_lnet_proc_files "stats"
21369         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21370         remove_lnet_proc_files "stats"
21371
21372         # lnet.routes should look like this:
21373         # Routing disabled/enabled
21374         # net hops priority state router
21375         # where net is a string like tcp0, hops > 0, priority >= 0,
21376         # state is up/down,
21377         # router is a string like 192.168.1.1@tcp2
21378         L1="^Routing (disabled|enabled)$"
21379         L2="^net +hops +priority +state +router$"
21380         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21381         create_lnet_proc_files "routes"
21382         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21383         remove_lnet_proc_files "routes"
21384
21385         # lnet.routers should look like this:
21386         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21387         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21388         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21389         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21390         L1="^ref +rtr_ref +alive +router$"
21391         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21392         create_lnet_proc_files "routers"
21393         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21394         remove_lnet_proc_files "routers"
21395
21396         # lnet.peers should look like this:
21397         # nid refs state last max rtr min tx min queue
21398         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21399         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21400         # numeric (0 or >0 or <0), queue >= 0.
21401         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21402         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21403         create_lnet_proc_files "peers"
21404         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21405         remove_lnet_proc_files "peers"
21406
21407         # lnet.buffers  should look like this:
21408         # pages count credits min
21409         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21410         L1="^pages +count +credits +min$"
21411         BR="^ +$N +$N +$I +$I$"
21412         create_lnet_proc_files "buffers"
21413         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21414         remove_lnet_proc_files "buffers"
21415
21416         # lnet.nis should look like this:
21417         # nid status alive refs peer rtr max tx min
21418         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21419         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21420         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21421         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21422         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21423         create_lnet_proc_files "nis"
21424         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21425         remove_lnet_proc_files "nis"
21426
21427         # can we successfully write to lnet.stats?
21428         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21429 }
21430 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21431
21432 test_216() { # bug 20317
21433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21434         remote_ost_nodsh && skip "remote OST with nodsh"
21435
21436         local node
21437         local facets=$(get_facets OST)
21438         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21439
21440         save_lustre_params client "osc.*.contention_seconds" > $p
21441         save_lustre_params $facets \
21442                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21443         save_lustre_params $facets \
21444                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21445         save_lustre_params $facets \
21446                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21447         clear_stats osc.*.osc_stats
21448
21449         # agressive lockless i/o settings
21450         do_nodes $(comma_list $(osts_nodes)) \
21451                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21452                         ldlm.namespaces.filter-*.contended_locks=0 \
21453                         ldlm.namespaces.filter-*.contention_seconds=60"
21454         lctl set_param -n osc.*.contention_seconds=60
21455
21456         $DIRECTIO write $DIR/$tfile 0 10 4096
21457         $CHECKSTAT -s 40960 $DIR/$tfile
21458
21459         # disable lockless i/o
21460         do_nodes $(comma_list $(osts_nodes)) \
21461                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21462                         ldlm.namespaces.filter-*.contended_locks=32 \
21463                         ldlm.namespaces.filter-*.contention_seconds=0"
21464         lctl set_param -n osc.*.contention_seconds=0
21465         clear_stats osc.*.osc_stats
21466
21467         dd if=/dev/zero of=$DIR/$tfile count=0
21468         $CHECKSTAT -s 0 $DIR/$tfile
21469
21470         restore_lustre_params <$p
21471         rm -f $p
21472         rm $DIR/$tfile
21473 }
21474 run_test 216 "check lockless direct write updates file size and kms correctly"
21475
21476 test_217() { # bug 22430
21477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21478
21479         local node
21480
21481         for node in $(nodes_list); do
21482                 local nid=$(host_nids_address $node $NETTYPE)
21483                 local node_ip=$(do_node $node getent ahostsv4 $node |
21484                                 awk '{ print $1; exit; }')
21485
21486                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21487                 # if hostname matches any NID, use hostname for better testing
21488                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21489                         echo "lctl ping node $node@$NETTYPE"
21490                         lctl ping $node@$NETTYPE ||
21491                                 error "ping $node@$NETTYPE failed rc=$?"
21492                 else # otherwise, at least test 'lctl ping' is working
21493                         echo "lctl ping nid $(h2nettype $nid)"
21494                         lctl ping $(h2nettype $nid) ||
21495                                 error "ping $(h2nettype $nid) failed rc=$?"
21496                         echo "skipping $node (no hyphen detected)"
21497                 fi
21498         done
21499
21500         return 0
21501 }
21502 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21503
21504 test_218() {
21505         # do directio so as not to populate the page cache
21506         log "creating a 10 Mb file"
21507         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21508                 error "multiop failed while creating a file"
21509         log "starting reads"
21510         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21511         log "truncating the file"
21512         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21513                 error "multiop failed while truncating the file"
21514         log "killing dd"
21515         kill %+ || true # reads might have finished
21516         echo "wait until dd is finished"
21517         wait
21518         log "removing the temporary file"
21519         rm -rf $DIR/$tfile || error "tmp file removal failed"
21520 }
21521 run_test 218 "parallel read and truncate should not deadlock"
21522
21523 test_219() {
21524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21525
21526         # write one partial page
21527         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21528         # set no grant so vvp_io_commit_write will do sync write
21529         $LCTL set_param fail_loc=0x411
21530         # write a full page at the end of file
21531         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21532
21533         $LCTL set_param fail_loc=0
21534         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21535         $LCTL set_param fail_loc=0x411
21536         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21537
21538         # LU-4201
21539         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21540         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21541 }
21542 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21543
21544 test_220() { #LU-325
21545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21546         remote_ost_nodsh && skip "remote OST with nodsh"
21547         remote_mds_nodsh && skip "remote MDS with nodsh"
21548         remote_mgs_nodsh && skip "remote MGS with nodsh"
21549
21550         local OSTIDX=0
21551
21552         # create on MDT0000 so the last_id and next_id are correct
21553         mkdir_on_mdt0 $DIR/$tdir
21554         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21555         OST=${OST%_UUID}
21556
21557         # on the mdt's osc
21558         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21559         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21560                         osp.$mdtosc_proc1.prealloc_last_id)
21561         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21562                         osp.$mdtosc_proc1.prealloc_next_id)
21563
21564         $LFS df -i
21565
21566         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21567         #define OBD_FAIL_OST_ENOINO              0x229
21568         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21569         create_pool $FSNAME.$TESTNAME || return 1
21570         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21571
21572         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21573
21574         MDSOBJS=$((last_id - next_id))
21575         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21576
21577         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21578         echo "OST still has $count kbytes free"
21579
21580         echo "create $MDSOBJS files @next_id..."
21581         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21582
21583         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21584                         osp.$mdtosc_proc1.prealloc_last_id)
21585         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21586                         osp.$mdtosc_proc1.prealloc_next_id)
21587
21588         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21589         $LFS df -i
21590
21591         echo "cleanup..."
21592
21593         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21594         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21595
21596         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21597                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21598         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21599                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21600         echo "unlink $MDSOBJS files @$next_id..."
21601         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21602 }
21603 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21604
21605 test_221() {
21606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21607
21608         dd if=`which date` of=$MOUNT/date oflag=sync
21609         chmod +x $MOUNT/date
21610
21611         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21612         $LCTL set_param fail_loc=0x80001401
21613
21614         $MOUNT/date > /dev/null
21615         rm -f $MOUNT/date
21616 }
21617 run_test 221 "make sure fault and truncate race to not cause OOM"
21618
21619 test_222a () {
21620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21621
21622         rm -rf $DIR/$tdir
21623         test_mkdir $DIR/$tdir
21624         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21625         createmany -o $DIR/$tdir/$tfile 10
21626         cancel_lru_locks mdc
21627         cancel_lru_locks osc
21628         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21629         $LCTL set_param fail_loc=0x31a
21630         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21631         $LCTL set_param fail_loc=0
21632         rm -r $DIR/$tdir
21633 }
21634 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21635
21636 test_222b () {
21637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21638
21639         rm -rf $DIR/$tdir
21640         test_mkdir $DIR/$tdir
21641         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21642         createmany -o $DIR/$tdir/$tfile 10
21643         cancel_lru_locks mdc
21644         cancel_lru_locks osc
21645         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21646         $LCTL set_param fail_loc=0x31a
21647         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21648         $LCTL set_param fail_loc=0
21649 }
21650 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21651
21652 test_223 () {
21653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21654
21655         rm -rf $DIR/$tdir
21656         test_mkdir $DIR/$tdir
21657         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21658         createmany -o $DIR/$tdir/$tfile 10
21659         cancel_lru_locks mdc
21660         cancel_lru_locks osc
21661         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21662         $LCTL set_param fail_loc=0x31b
21663         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21664         $LCTL set_param fail_loc=0
21665         rm -r $DIR/$tdir
21666 }
21667 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21668
21669 test_224a() { # LU-1039, MRP-303
21670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21671         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21672         $LCTL set_param fail_loc=0x508
21673         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21674         $LCTL set_param fail_loc=0
21675         df $DIR
21676 }
21677 run_test 224a "Don't panic on bulk IO failure"
21678
21679 test_224bd_sub() { # LU-1039, MRP-303
21680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21681         local timeout=$1
21682
21683         shift
21684         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21685
21686         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21687
21688         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21689         cancel_lru_locks osc
21690         set_checksums 0
21691         stack_trap "set_checksums $ORIG_CSUM" EXIT
21692         local at_max_saved=0
21693
21694         # adaptive timeouts may prevent seeing the issue
21695         if at_is_enabled; then
21696                 at_max_saved=$(at_max_get mds)
21697                 at_max_set 0 mds client
21698                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21699         fi
21700
21701         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21702         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21703         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21704
21705         do_facet ost1 $LCTL set_param fail_loc=0
21706         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21707         df $DIR
21708 }
21709
21710 test_224b() {
21711         test_224bd_sub 3 error "dd failed"
21712 }
21713 run_test 224b "Don't panic on bulk IO failure"
21714
21715 test_224c() { # LU-6441
21716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21717         remote_mds_nodsh && skip "remote MDS with nodsh"
21718
21719         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21720         save_writethrough $p
21721         set_cache writethrough on
21722
21723         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21724         local at_max=$($LCTL get_param -n at_max)
21725         local timeout=$($LCTL get_param -n timeout)
21726         local test_at="at_max"
21727         local param_at="$FSNAME.sys.at_max"
21728         local test_timeout="timeout"
21729         local param_timeout="$FSNAME.sys.timeout"
21730
21731         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21732
21733         set_persistent_param_and_check client "$test_at" "$param_at" 0
21734         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21735
21736         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21737         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21738         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21739         stack_trap "rm -f $DIR/$tfile"
21740         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21741         sync
21742         do_facet ost1 "$LCTL set_param fail_loc=0"
21743
21744         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21745         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21746                 $timeout
21747
21748         $LCTL set_param -n $pages_per_rpc
21749         restore_lustre_params < $p
21750         rm -f $p
21751 }
21752 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21753
21754 test_224d() { # LU-11169
21755         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21756 }
21757 run_test 224d "Don't corrupt data on bulk IO timeout"
21758
21759 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21760 test_225a () {
21761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21762         if [ -z ${MDSSURVEY} ]; then
21763                 skip_env "mds-survey not found"
21764         fi
21765         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21766                 skip "Need MDS version at least 2.2.51"
21767
21768         local mds=$(facet_host $SINGLEMDS)
21769         local target=$(do_nodes $mds 'lctl dl' |
21770                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21771
21772         local cmd1="file_count=1000 thrhi=4"
21773         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21774         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21775         local cmd="$cmd1 $cmd2 $cmd3"
21776
21777         rm -f ${TMP}/mds_survey*
21778         echo + $cmd
21779         eval $cmd || error "mds-survey with zero-stripe failed"
21780         cat ${TMP}/mds_survey*
21781         rm -f ${TMP}/mds_survey*
21782 }
21783 run_test 225a "Metadata survey sanity with zero-stripe"
21784
21785 test_225b () {
21786         if [ -z ${MDSSURVEY} ]; then
21787                 skip_env "mds-survey not found"
21788         fi
21789         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21790                 skip "Need MDS version at least 2.2.51"
21791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21792         remote_mds_nodsh && skip "remote MDS with nodsh"
21793         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21794                 skip_env "Need to mount OST to test"
21795         fi
21796
21797         local mds=$(facet_host $SINGLEMDS)
21798         local target=$(do_nodes $mds 'lctl dl' |
21799                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21800
21801         local cmd1="file_count=1000 thrhi=4"
21802         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21803         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21804         local cmd="$cmd1 $cmd2 $cmd3"
21805
21806         rm -f ${TMP}/mds_survey*
21807         echo + $cmd
21808         eval $cmd || error "mds-survey with stripe_count failed"
21809         cat ${TMP}/mds_survey*
21810         rm -f ${TMP}/mds_survey*
21811 }
21812 run_test 225b "Metadata survey sanity with stripe_count = 1"
21813
21814 mcreate_path2fid () {
21815         local mode=$1
21816         local major=$2
21817         local minor=$3
21818         local name=$4
21819         local desc=$5
21820         local path=$DIR/$tdir/$name
21821         local fid
21822         local rc
21823         local fid_path
21824
21825         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21826                 error "cannot create $desc"
21827
21828         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21829         rc=$?
21830         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21831
21832         fid_path=$($LFS fid2path $MOUNT $fid)
21833         rc=$?
21834         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21835
21836         [ "$path" == "$fid_path" ] ||
21837                 error "fid2path returned $fid_path, expected $path"
21838
21839         echo "pass with $path and $fid"
21840 }
21841
21842 test_226a () {
21843         rm -rf $DIR/$tdir
21844         mkdir -p $DIR/$tdir
21845
21846         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21847         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21848         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21849         mcreate_path2fid 0040666 0 0 dir "directory"
21850         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21851         mcreate_path2fid 0100666 0 0 file "regular file"
21852         mcreate_path2fid 0120666 0 0 link "symbolic link"
21853         mcreate_path2fid 0140666 0 0 sock "socket"
21854 }
21855 run_test 226a "call path2fid and fid2path on files of all type"
21856
21857 test_226b () {
21858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21859
21860         local MDTIDX=1
21861
21862         rm -rf $DIR/$tdir
21863         mkdir -p $DIR/$tdir
21864         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21865                 error "create remote directory failed"
21866         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21867         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21868                                 "character special file (null)"
21869         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21870                                 "character special file (no device)"
21871         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21872         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21873                                 "block special file (loop)"
21874         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21875         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21876         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21877 }
21878 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21879
21880 test_226c () {
21881         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21882         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21883                 skip "Need MDS version at least 2.13.55"
21884
21885         local submnt=/mnt/submnt
21886         local srcfile=/etc/passwd
21887         local dstfile=$submnt/passwd
21888         local path
21889         local fid
21890
21891         rm -rf $DIR/$tdir
21892         rm -rf $submnt
21893         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21894                 error "create remote directory failed"
21895         mkdir -p $submnt || error "create $submnt failed"
21896         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21897                 error "mount $submnt failed"
21898         stack_trap "umount $submnt" EXIT
21899
21900         cp $srcfile $dstfile
21901         fid=$($LFS path2fid $dstfile)
21902         path=$($LFS fid2path $submnt "$fid")
21903         [ "$path" = "$dstfile" ] ||
21904                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21905 }
21906 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21907
21908 test_226d () {
21909         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21910                 skip "Need client at least version 2.15.57"
21911
21912         # Define First test dataset
21913         local testdirs_01=$DIR/$tdir
21914         local testdata_01=$testdirs_01/${tdir}_01
21915         local testresult_01=${tdir}_01
21916         # Define Second test dataset
21917         local testdirs_02=$DIR/$tdir/$tdir
21918         local testdata_02=$testdirs_02/${tdir}_02
21919         local testresult_02=${tdir}_02
21920         # Define third test dataset (top level)
21921         local testdata_03=$DIR/${tdir}_03
21922         local testresult_03=${tdir}_03
21923
21924         # Create first test dataset
21925         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21926         touch $testdata_01 || error "cannot create file $testdata_01"
21927
21928         # Create second test dataset
21929         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21930         touch $testdata_02 || error "cannot create file $testdata_02"
21931
21932         # Create third test dataset
21933         touch $testdata_03 || error "cannot create file $testdata_03"
21934
21935         local fid01=$($LFS getstripe -F "$testdata_01") ||
21936                 error "getstripe failed on $testdata_01"
21937         local fid02=$($LFS getstripe -F "$testdata_02") ||
21938                 error "getstripe failed on $testdata_01"
21939         local fid03=$($LFS getstripe -F "$testdata_03") ||
21940                 error "getstripe failed on $testdata_03"
21941
21942         # Verify only -n option
21943         local out1=$($LFS fid2path -n $DIR $fid01) ||
21944                 error "fid2path failed on $fid01"
21945         local out2=$($LFS fid2path -n $DIR $fid02) ||
21946                 error "fid2path failed on $fid02"
21947         local out3=$($LFS fid2path -n $DIR $fid03) ||
21948                 error "fid2path failed on $fid03"
21949
21950         [[ "$out1" == "$testresult_01" ]] ||
21951                 error "fid2path failed: Expected $testresult_01 got $out1"
21952         [[ "$out2" == "$testresult_02" ]] ||
21953                 error "fid2path failed: Expected $testresult_02 got $out2"
21954         [[ "$out3" == "$testresult_03" ]] ||
21955                 error "fid2path failed: Expected $testresult_03 got $out3"
21956
21957         # Verify with option -fn together
21958         out1=$($LFS fid2path -fn $DIR $fid01) ||
21959                 error "fid2path -fn failed on $fid01"
21960         out2=$($LFS fid2path -fn $DIR $fid02) ||
21961                 error "fid2path -fn failed on $fid02"
21962         out3=$($LFS fid2path -fn $DIR $fid03) ||
21963                 error "fid2path -fn failed on $fid03"
21964
21965         local tmpout=$(echo $out1 | cut -d" " -f2)
21966         [[ "$tmpout" == "$testresult_01" ]] ||
21967                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21968
21969         tmpout=$(echo $out2 | cut -d" " -f2)
21970         [[ "$tmpout" == "$testresult_02" ]] ||
21971                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21972
21973         tmpout=$(echo $out3 | cut -d" " -f2)
21974         [[ "$tmpout" == "$testresult_03" ]] ||
21975                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21976 }
21977 run_test 226d "verify fid2path with -n and -fn option"
21978
21979 test_226e () {
21980         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21981                 skip "Need client at least version 2.15.56"
21982
21983         # Define filename with 'newline' and a space
21984         local testfile="Test"$'\n'"file 01"
21985         # Define link name with multiple 'newline' and a space
21986         local linkfile="Link"$'\n'"file "$'\n'"01"
21987         # Remove prior hard link
21988         rm -f $DIR/"$linkfile"
21989
21990         # Create file
21991         touch $DIR/"$testfile"
21992         # Create link
21993         ln $DIR/"$testfile" $DIR/"$linkfile"
21994
21995         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21996                 error "getstripe failed on $DIR/$testfile"
21997
21998         # Call with -0 option
21999         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
22000                 echo "FILE:" | grep -c "FILE:")
22001
22002         # With -0 option the output should be exactly 2 lines.
22003         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
22004 }
22005 run_test 226e "Verify path2fid -0 option with newline and space"
22006
22007 # LU-1299 Executing or running ldd on a truncated executable does not
22008 # cause an out-of-memory condition.
22009 test_227() {
22010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22011         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
22012
22013         dd if=$(which date) of=$MOUNT/date bs=1k count=1
22014         chmod +x $MOUNT/date
22015
22016         $MOUNT/date > /dev/null
22017         ldd $MOUNT/date > /dev/null
22018         rm -f $MOUNT/date
22019 }
22020 run_test 227 "running truncated executable does not cause OOM"
22021
22022 # LU-1512 try to reuse idle OI blocks
22023 test_228a() {
22024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22025         remote_mds_nodsh && skip "remote MDS with nodsh"
22026         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22027
22028         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22029         local myDIR=$DIR/$tdir
22030
22031         mkdir -p $myDIR
22032         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22033         $LCTL set_param fail_loc=0x80001002
22034         createmany -o $myDIR/t- 10000
22035         $LCTL set_param fail_loc=0
22036         # The guard is current the largest FID holder
22037         touch $myDIR/guard
22038         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22039                     tr -d '[')
22040         local IDX=$(($SEQ % 64))
22041
22042         do_facet $SINGLEMDS sync
22043         # Make sure journal flushed.
22044         sleep 6
22045         local blk1=$(do_facet $SINGLEMDS \
22046                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22047                      grep Blockcount | awk '{print $4}')
22048
22049         # Remove old files, some OI blocks will become idle.
22050         unlinkmany $myDIR/t- 10000
22051         # Create new files, idle OI blocks should be reused.
22052         createmany -o $myDIR/t- 2000
22053         do_facet $SINGLEMDS sync
22054         # Make sure journal flushed.
22055         sleep 6
22056         local blk2=$(do_facet $SINGLEMDS \
22057                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22058                      grep Blockcount | awk '{print $4}')
22059
22060         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22061 }
22062 run_test 228a "try to reuse idle OI blocks"
22063
22064 test_228b() {
22065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22066         remote_mds_nodsh && skip "remote MDS with nodsh"
22067         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22068
22069         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22070         local myDIR=$DIR/$tdir
22071
22072         mkdir -p $myDIR
22073         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22074         $LCTL set_param fail_loc=0x80001002
22075         createmany -o $myDIR/t- 10000
22076         $LCTL set_param fail_loc=0
22077         # The guard is current the largest FID holder
22078         touch $myDIR/guard
22079         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22080                     tr -d '[')
22081         local IDX=$(($SEQ % 64))
22082
22083         do_facet $SINGLEMDS sync
22084         # Make sure journal flushed.
22085         sleep 6
22086         local blk1=$(do_facet $SINGLEMDS \
22087                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22088                      grep Blockcount | awk '{print $4}')
22089
22090         # Remove old files, some OI blocks will become idle.
22091         unlinkmany $myDIR/t- 10000
22092
22093         # stop the MDT
22094         stop $SINGLEMDS || error "Fail to stop MDT."
22095         # remount the MDT
22096         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22097                 error "Fail to start MDT."
22098
22099         client_up || error "Fail to df."
22100         # Create new files, idle OI blocks should be reused.
22101         createmany -o $myDIR/t- 2000
22102         do_facet $SINGLEMDS sync
22103         # Make sure journal flushed.
22104         sleep 6
22105         local blk2=$(do_facet $SINGLEMDS \
22106                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22107                      grep Blockcount | awk '{print $4}')
22108
22109         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22110 }
22111 run_test 228b "idle OI blocks can be reused after MDT restart"
22112
22113 #LU-1881
22114 test_228c() {
22115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22116         remote_mds_nodsh && skip "remote MDS with nodsh"
22117         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22118
22119         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22120         local myDIR=$DIR/$tdir
22121
22122         mkdir -p $myDIR
22123         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22124         $LCTL set_param fail_loc=0x80001002
22125         # 20000 files can guarantee there are index nodes in the OI file
22126         createmany -o $myDIR/t- 20000
22127         $LCTL set_param fail_loc=0
22128         # The guard is current the largest FID holder
22129         touch $myDIR/guard
22130         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22131                     tr -d '[')
22132         local IDX=$(($SEQ % 64))
22133
22134         do_facet $SINGLEMDS sync
22135         # Make sure journal flushed.
22136         sleep 6
22137         local blk1=$(do_facet $SINGLEMDS \
22138                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22139                      grep Blockcount | awk '{print $4}')
22140
22141         # Remove old files, some OI blocks will become idle.
22142         unlinkmany $myDIR/t- 20000
22143         rm -f $myDIR/guard
22144         # The OI file should become empty now
22145
22146         # Create new files, idle OI blocks should be reused.
22147         createmany -o $myDIR/t- 2000
22148         do_facet $SINGLEMDS sync
22149         # Make sure journal flushed.
22150         sleep 6
22151         local blk2=$(do_facet $SINGLEMDS \
22152                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22153                      grep Blockcount | awk '{print $4}')
22154
22155         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22156 }
22157 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22158
22159 test_229() { # LU-2482, LU-3448
22160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22161         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22162         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22163                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22164
22165         rm -f $DIR/$tfile
22166
22167         # Create a file with a released layout and stripe count 2.
22168         $MULTIOP $DIR/$tfile H2c ||
22169                 error "failed to create file with released layout"
22170
22171         $LFS getstripe -v $DIR/$tfile
22172
22173         local pattern=$($LFS getstripe -L $DIR/$tfile)
22174         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22175
22176         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22177                 error "getstripe"
22178         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22179         stat $DIR/$tfile || error "failed to stat released file"
22180
22181         chown $RUNAS_ID $DIR/$tfile ||
22182                 error "chown $RUNAS_ID $DIR/$tfile failed"
22183
22184         chgrp $RUNAS_ID $DIR/$tfile ||
22185                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22186
22187         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22188         rm $DIR/$tfile || error "failed to remove released file"
22189 }
22190 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22191
22192 test_230a() {
22193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22195         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22196                 skip "Need MDS version at least 2.11.52"
22197
22198         local MDTIDX=1
22199
22200         test_mkdir $DIR/$tdir
22201         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22202         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22203         [ $mdt_idx -ne 0 ] &&
22204                 error "create local directory on wrong MDT $mdt_idx"
22205
22206         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22207                         error "create remote directory failed"
22208         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22209         [ $mdt_idx -ne $MDTIDX ] &&
22210                 error "create remote directory on wrong MDT $mdt_idx"
22211
22212         createmany -o $DIR/$tdir/test_230/t- 10 ||
22213                 error "create files on remote directory failed"
22214         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22215         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22216         rm -r $DIR/$tdir || error "unlink remote directory failed"
22217 }
22218 run_test 230a "Create remote directory and files under the remote directory"
22219
22220 test_230b() {
22221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22222         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22223         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22224                 skip "Need MDS version at least 2.11.52"
22225
22226         local MDTIDX=1
22227         local mdt_index
22228         local i
22229         local file
22230         local pid
22231         local stripe_count
22232         local migrate_dir=$DIR/$tdir/migrate_dir
22233         local other_dir=$DIR/$tdir/other_dir
22234
22235         test_mkdir $DIR/$tdir
22236         test_mkdir -i0 -c1 $migrate_dir
22237         test_mkdir -i0 -c1 $other_dir
22238         for ((i=0; i<10; i++)); do
22239                 mkdir -p $migrate_dir/dir_${i}
22240                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22241                         error "create files under remote dir failed $i"
22242         done
22243
22244         cp /etc/passwd $migrate_dir/$tfile
22245         cp /etc/passwd $other_dir/$tfile
22246         chattr +SAD $migrate_dir
22247         chattr +SAD $migrate_dir/$tfile
22248
22249         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22250         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22251         local old_dir_mode=$(stat -c%f $migrate_dir)
22252         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22253
22254         mkdir -p $migrate_dir/dir_default_stripe2
22255         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22256         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22257
22258         mkdir -p $other_dir
22259         ln $migrate_dir/$tfile $other_dir/luna
22260         ln $migrate_dir/$tfile $migrate_dir/sofia
22261         ln $other_dir/$tfile $migrate_dir/david
22262         ln -s $migrate_dir/$tfile $other_dir/zachary
22263         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22264         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22265
22266         local len
22267         local lnktgt
22268
22269         # inline symlink
22270         for len in 58 59 60; do
22271                 lnktgt=$(str_repeat 'l' $len)
22272                 touch $migrate_dir/$lnktgt
22273                 ln -s $lnktgt $migrate_dir/${len}char_ln
22274         done
22275
22276         # PATH_MAX
22277         for len in 4094 4095; do
22278                 lnktgt=$(str_repeat 'l' $len)
22279                 ln -s $lnktgt $migrate_dir/${len}char_ln
22280         done
22281
22282         # NAME_MAX
22283         for len in 254 255; do
22284                 touch $migrate_dir/$(str_repeat 'l' $len)
22285         done
22286
22287         $LFS migrate -m $MDTIDX $migrate_dir ||
22288                 error "fails on migrating remote dir to MDT1"
22289
22290         echo "migratate to MDT1, then checking.."
22291         for ((i = 0; i < 10; i++)); do
22292                 for file in $(find $migrate_dir/dir_${i}); do
22293                         mdt_index=$($LFS getstripe -m $file)
22294                         # broken symlink getstripe will fail
22295                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22296                                 error "$file is not on MDT${MDTIDX}"
22297                 done
22298         done
22299
22300         # the multiple link file should still in MDT0
22301         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22302         [ $mdt_index == 0 ] ||
22303                 error "$file is not on MDT${MDTIDX}"
22304
22305         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22306         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22307                 error " expect $old_dir_flag get $new_dir_flag"
22308
22309         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22310         [ "$old_file_flag" = "$new_file_flag" ] ||
22311                 error " expect $old_file_flag get $new_file_flag"
22312
22313         local new_dir_mode=$(stat -c%f $migrate_dir)
22314         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22315                 error "expect mode $old_dir_mode get $new_dir_mode"
22316
22317         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22318         [ "$old_file_mode" = "$new_file_mode" ] ||
22319                 error "expect mode $old_file_mode get $new_file_mode"
22320
22321         diff /etc/passwd $migrate_dir/$tfile ||
22322                 error "$tfile different after migration"
22323
22324         diff /etc/passwd $other_dir/luna ||
22325                 error "luna different after migration"
22326
22327         diff /etc/passwd $migrate_dir/sofia ||
22328                 error "sofia different after migration"
22329
22330         diff /etc/passwd $migrate_dir/david ||
22331                 error "david different after migration"
22332
22333         diff /etc/passwd $other_dir/zachary ||
22334                 error "zachary different after migration"
22335
22336         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22337                 error "${tfile}_ln different after migration"
22338
22339         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22340                 error "${tfile}_ln_other different after migration"
22341
22342         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22343         [ $stripe_count = 2 ] ||
22344                 error "dir strpe_count $d != 2 after migration."
22345
22346         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22347         [ $stripe_count = 2 ] ||
22348                 error "file strpe_count $d != 2 after migration."
22349
22350         #migrate back to MDT0
22351         MDTIDX=0
22352
22353         $LFS migrate -m $MDTIDX $migrate_dir ||
22354                 error "fails on migrating remote dir to MDT0"
22355
22356         echo "migrate back to MDT0, checking.."
22357         for file in $(find $migrate_dir); do
22358                 mdt_index=$($LFS getstripe -m $file)
22359                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22360                         error "$file is not on MDT${MDTIDX}"
22361         done
22362
22363         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22364         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22365                 error " expect $old_dir_flag get $new_dir_flag"
22366
22367         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22368         [ "$old_file_flag" = "$new_file_flag" ] ||
22369                 error " expect $old_file_flag get $new_file_flag"
22370
22371         local new_dir_mode=$(stat -c%f $migrate_dir)
22372         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22373                 error "expect mode $old_dir_mode get $new_dir_mode"
22374
22375         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22376         [ "$old_file_mode" = "$new_file_mode" ] ||
22377                 error "expect mode $old_file_mode get $new_file_mode"
22378
22379         diff /etc/passwd ${migrate_dir}/$tfile ||
22380                 error "$tfile different after migration"
22381
22382         diff /etc/passwd ${other_dir}/luna ||
22383                 error "luna different after migration"
22384
22385         diff /etc/passwd ${migrate_dir}/sofia ||
22386                 error "sofia different after migration"
22387
22388         diff /etc/passwd ${other_dir}/zachary ||
22389                 error "zachary different after migration"
22390
22391         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22392                 error "${tfile}_ln different after migration"
22393
22394         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22395                 error "${tfile}_ln_other different after migration"
22396
22397         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22398         [ $stripe_count = 2 ] ||
22399                 error "dir strpe_count $d != 2 after migration."
22400
22401         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22402         [ $stripe_count = 2 ] ||
22403                 error "file strpe_count $d != 2 after migration."
22404
22405         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22406 }
22407 run_test 230b "migrate directory"
22408
22409 test_230c() {
22410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22411         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22412         remote_mds_nodsh && skip "remote MDS with nodsh"
22413         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22414                 skip "Need MDS version at least 2.11.52"
22415
22416         local MDTIDX=1
22417         local total=3
22418         local mdt_index
22419         local file
22420         local migrate_dir=$DIR/$tdir/migrate_dir
22421
22422         #If migrating directory fails in the middle, all entries of
22423         #the directory is still accessiable.
22424         test_mkdir $DIR/$tdir
22425         test_mkdir -i0 -c1 $migrate_dir
22426         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22427         stat $migrate_dir
22428         createmany -o $migrate_dir/f $total ||
22429                 error "create files under ${migrate_dir} failed"
22430
22431         # fail after migrating top dir, and this will fail only once, so the
22432         # first sub file migration will fail (currently f3), others succeed.
22433         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22434         do_facet mds1 lctl set_param fail_loc=0x1801
22435         local t=$(ls $migrate_dir | wc -l)
22436         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22437                 error "migrate should fail"
22438         local u=$(ls $migrate_dir | wc -l)
22439         [ "$u" == "$t" ] || error "$u != $t during migration"
22440
22441         # add new dir/file should succeed
22442         mkdir $migrate_dir/dir ||
22443                 error "mkdir failed under migrating directory"
22444         touch $migrate_dir/file ||
22445                 error "create file failed under migrating directory"
22446
22447         # add file with existing name should fail
22448         for file in $migrate_dir/f*; do
22449                 stat $file > /dev/null || error "stat $file failed"
22450                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22451                         error "open(O_CREAT|O_EXCL) $file should fail"
22452                 $MULTIOP $file m && error "create $file should fail"
22453                 touch $DIR/$tdir/remote_dir/$tfile ||
22454                         error "touch $tfile failed"
22455                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22456                         error "link $file should fail"
22457                 mdt_index=$($LFS getstripe -m $file)
22458                 if [ $mdt_index == 0 ]; then
22459                         # file failed to migrate is not allowed to rename to
22460                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22461                                 error "rename to $file should fail"
22462                 else
22463                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22464                                 error "rename to $file failed"
22465                 fi
22466                 echo hello >> $file || error "write $file failed"
22467         done
22468
22469         # resume migration with different options should fail
22470         $LFS migrate -m 0 $migrate_dir &&
22471                 error "migrate -m 0 $migrate_dir should fail"
22472
22473         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22474                 error "migrate -c 2 $migrate_dir should fail"
22475
22476         # resume migration should succeed
22477         $LFS migrate -m $MDTIDX $migrate_dir ||
22478                 error "migrate $migrate_dir failed"
22479
22480         echo "Finish migration, then checking.."
22481         for file in $(find $migrate_dir); do
22482                 mdt_index=$($LFS getstripe -m $file)
22483                 [ $mdt_index == $MDTIDX ] ||
22484                         error "$file is not on MDT${MDTIDX}"
22485         done
22486
22487         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22488 }
22489 run_test 230c "check directory accessiblity if migration failed"
22490
22491 test_230d() {
22492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22493         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22494         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22495                 skip "Need MDS version at least 2.11.52"
22496         # LU-11235
22497         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22498
22499         local migrate_dir=$DIR/$tdir/migrate_dir
22500         local old_index
22501         local new_index
22502         local old_count
22503         local new_count
22504         local new_hash
22505         local mdt_index
22506         local i
22507         local j
22508
22509         old_index=$((RANDOM % MDSCOUNT))
22510         old_count=$((MDSCOUNT - old_index))
22511         new_index=$((RANDOM % MDSCOUNT))
22512         new_count=$((MDSCOUNT - new_index))
22513         new_hash=1 # for all_char
22514
22515         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22516         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22517
22518         test_mkdir $DIR/$tdir
22519         test_mkdir -i $old_index -c $old_count $migrate_dir
22520
22521         for ((i=0; i<100; i++)); do
22522                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22523                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22524                         error "create files under remote dir failed $i"
22525         done
22526
22527         echo -n "Migrate from MDT$old_index "
22528         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22529         echo -n "to MDT$new_index"
22530         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22531         echo
22532
22533         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22534         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22535                 error "migrate remote dir error"
22536
22537         echo "Finish migration, then checking.."
22538         for file in $(find $migrate_dir -maxdepth 1); do
22539                 mdt_index=$($LFS getstripe -m $file)
22540                 if [ $mdt_index -lt $new_index ] ||
22541                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22542                         error "$file is on MDT$mdt_index"
22543                 fi
22544         done
22545
22546         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22547 }
22548 run_test 230d "check migrate big directory"
22549
22550 test_230e() {
22551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22552         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22553         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22554                 skip "Need MDS version at least 2.11.52"
22555
22556         local i
22557         local j
22558         local a_fid
22559         local b_fid
22560
22561         mkdir_on_mdt0 $DIR/$tdir
22562         mkdir $DIR/$tdir/migrate_dir
22563         mkdir $DIR/$tdir/other_dir
22564         touch $DIR/$tdir/migrate_dir/a
22565         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22566         ls $DIR/$tdir/other_dir
22567
22568         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22569                 error "migrate dir fails"
22570
22571         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22572         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22573
22574         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22575         [ $mdt_index == 0 ] || error "a is not on MDT0"
22576
22577         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22578                 error "migrate dir fails"
22579
22580         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22581         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22582
22583         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22584         [ $mdt_index == 1 ] || error "a is not on MDT1"
22585
22586         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22587         [ $mdt_index == 1 ] || error "b is not on MDT1"
22588
22589         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22590         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22591
22592         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22593
22594         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22595 }
22596 run_test 230e "migrate mulitple local link files"
22597
22598 test_230f() {
22599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22601         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22602                 skip "Need MDS version at least 2.11.52"
22603
22604         local a_fid
22605         local ln_fid
22606
22607         mkdir -p $DIR/$tdir
22608         mkdir $DIR/$tdir/migrate_dir
22609         $LFS mkdir -i1 $DIR/$tdir/other_dir
22610         touch $DIR/$tdir/migrate_dir/a
22611         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22612         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22613         ls $DIR/$tdir/other_dir
22614
22615         # a should be migrated to MDT1, since no other links on MDT0
22616         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22617                 error "#1 migrate dir fails"
22618         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22619         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22620         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22621         [ $mdt_index == 1 ] || error "a is not on MDT1"
22622
22623         # a should stay on MDT1, because it is a mulitple link file
22624         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22625                 error "#2 migrate dir fails"
22626         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22627         [ $mdt_index == 1 ] || error "a is not on MDT1"
22628
22629         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22630                 error "#3 migrate dir fails"
22631
22632         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22633         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22634         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22635
22636         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22637         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22638
22639         # a should be migrated to MDT0, since no other links on MDT1
22640         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22641                 error "#4 migrate dir fails"
22642         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22643         [ $mdt_index == 0 ] || error "a is not on MDT0"
22644
22645         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22646 }
22647 run_test 230f "migrate mulitple remote link files"
22648
22649 test_230g() {
22650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22652         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22653                 skip "Need MDS version at least 2.11.52"
22654
22655         mkdir -p $DIR/$tdir/migrate_dir
22656
22657         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22658                 error "migrating dir to non-exist MDT succeeds"
22659         true
22660 }
22661 run_test 230g "migrate dir to non-exist MDT"
22662
22663 test_230h() {
22664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22665         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22666         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22667                 skip "Need MDS version at least 2.11.52"
22668
22669         local mdt_index
22670
22671         mkdir -p $DIR/$tdir/migrate_dir
22672
22673         $LFS migrate -m1 $DIR &&
22674                 error "migrating mountpoint1 should fail"
22675
22676         $LFS migrate -m1 $DIR/$tdir/.. &&
22677                 error "migrating mountpoint2 should fail"
22678
22679         # same as mv
22680         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22681                 error "migrating $tdir/migrate_dir/.. should fail"
22682
22683         true
22684 }
22685 run_test 230h "migrate .. and root"
22686
22687 test_230i() {
22688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22689         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22690         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22691                 skip "Need MDS version at least 2.11.52"
22692
22693         mkdir -p $DIR/$tdir/migrate_dir
22694
22695         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22696                 error "migration fails with a tailing slash"
22697
22698         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22699                 error "migration fails with two tailing slashes"
22700 }
22701 run_test 230i "lfs migrate -m tolerates trailing slashes"
22702
22703 test_230j() {
22704         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22705         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22706                 skip "Need MDS version at least 2.11.52"
22707
22708         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22709         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22710                 error "create $tfile failed"
22711         cat /etc/passwd > $DIR/$tdir/$tfile
22712
22713         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22714
22715         cmp /etc/passwd $DIR/$tdir/$tfile ||
22716                 error "DoM file mismatch after migration"
22717 }
22718 run_test 230j "DoM file data not changed after dir migration"
22719
22720 test_230k() {
22721         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22722         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22723                 skip "Need MDS version at least 2.11.56"
22724
22725         local total=20
22726         local files_on_starting_mdt=0
22727
22728         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22729         $LFS getdirstripe $DIR/$tdir
22730         for i in $(seq $total); do
22731                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22732                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22733                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22734         done
22735
22736         echo "$files_on_starting_mdt files on MDT0"
22737
22738         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22739         $LFS getdirstripe $DIR/$tdir
22740
22741         files_on_starting_mdt=0
22742         for i in $(seq $total); do
22743                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22744                         error "file $tfile.$i mismatch after migration"
22745                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22746                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22747         done
22748
22749         echo "$files_on_starting_mdt files on MDT1 after migration"
22750         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22751
22752         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22753         $LFS getdirstripe $DIR/$tdir
22754
22755         files_on_starting_mdt=0
22756         for i in $(seq $total); do
22757                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22758                         error "file $tfile.$i mismatch after 2nd migration"
22759                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22760                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22761         done
22762
22763         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22764         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22765
22766         true
22767 }
22768 run_test 230k "file data not changed after dir migration"
22769
22770 test_230l() {
22771         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22772         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22773                 skip "Need MDS version at least 2.11.56"
22774
22775         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22776         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22777                 error "create files under remote dir failed $i"
22778         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22779 }
22780 run_test 230l "readdir between MDTs won't crash"
22781
22782 test_230m() {
22783         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22784         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22785                 skip "Need MDS version at least 2.11.56"
22786
22787         local MDTIDX=1
22788         local mig_dir=$DIR/$tdir/migrate_dir
22789         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22790         local shortstr="b"
22791         local val
22792
22793         echo "Creating files and dirs with xattrs"
22794         test_mkdir $DIR/$tdir
22795         test_mkdir -i0 -c1 $mig_dir
22796         mkdir $mig_dir/dir
22797         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22798                 error "cannot set xattr attr1 on dir"
22799         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22800                 error "cannot set xattr attr2 on dir"
22801         touch $mig_dir/dir/f0
22802         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22803                 error "cannot set xattr attr1 on file"
22804         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22805                 error "cannot set xattr attr2 on file"
22806         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22807         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22808         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22809         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22810         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22811         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22812         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22813         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22814         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22815
22816         echo "Migrating to MDT1"
22817         $LFS migrate -m $MDTIDX $mig_dir ||
22818                 error "fails on migrating dir to MDT1"
22819
22820         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22821         echo "Checking xattrs"
22822         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22823         [ "$val" = $longstr ] ||
22824                 error "expecting xattr1 $longstr on dir, found $val"
22825         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22826         [ "$val" = $shortstr ] ||
22827                 error "expecting xattr2 $shortstr on dir, found $val"
22828         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22829         [ "$val" = $longstr ] ||
22830                 error "expecting xattr1 $longstr on file, found $val"
22831         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22832         [ "$val" = $shortstr ] ||
22833                 error "expecting xattr2 $shortstr on file, found $val"
22834 }
22835 run_test 230m "xattrs not changed after dir migration"
22836
22837 test_230n() {
22838         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22839         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22840                 skip "Need MDS version at least 2.13.53"
22841
22842         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22843         cat /etc/hosts > $DIR/$tdir/$tfile
22844         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22845         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22846
22847         cmp /etc/hosts $DIR/$tdir/$tfile ||
22848                 error "File data mismatch after migration"
22849 }
22850 run_test 230n "Dir migration with mirrored file"
22851
22852 test_230o() {
22853         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22854         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22855                 skip "Need MDS version at least 2.13.52"
22856
22857         local mdts=$(comma_list $(mdts_nodes))
22858         local timeout=100
22859         local restripe_status
22860         local delta
22861         local i
22862
22863         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22864
22865         # in case "crush" hash type is not set
22866         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22867
22868         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22869                            mdt.*MDT0000.enable_dir_restripe)
22870         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22871         stack_trap "do_nodes $mdts $LCTL set_param \
22872                     mdt.*.enable_dir_restripe=$restripe_status"
22873
22874         mkdir $DIR/$tdir
22875         createmany -m $DIR/$tdir/f 100 ||
22876                 error "create files under remote dir failed $i"
22877         createmany -d $DIR/$tdir/d 100 ||
22878                 error "create dirs under remote dir failed $i"
22879
22880         for i in $(seq 2 $MDSCOUNT); do
22881                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22882                 $LFS setdirstripe -c $i $DIR/$tdir ||
22883                         error "split -c $i $tdir failed"
22884                 wait_update $HOSTNAME \
22885                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22886                         error "dir split not finished"
22887                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22888                         awk '/migrate/ {sum += $2} END { print sum }')
22889                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22890                 # delta is around total_files/stripe_count
22891                 (( $delta < 200 / (i - 1) + 4 )) ||
22892                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22893         done
22894 }
22895 run_test 230o "dir split"
22896
22897 test_230p() {
22898         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22899         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22900                 skip "Need MDS version at least 2.13.52"
22901
22902         local mdts=$(comma_list $(mdts_nodes))
22903         local timeout=100
22904         local restripe_status
22905         local delta
22906         local c
22907
22908         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22909
22910         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22911
22912         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22913                            mdt.*MDT0000.enable_dir_restripe)
22914         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22915         stack_trap "do_nodes $mdts $LCTL set_param \
22916                     mdt.*.enable_dir_restripe=$restripe_status"
22917
22918         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22919         createmany -m $DIR/$tdir/f 100 ||
22920                 error "create files under remote dir failed"
22921         createmany -d $DIR/$tdir/d 100 ||
22922                 error "create dirs under remote dir failed"
22923
22924         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22925                 local mdt_hash="crush"
22926
22927                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22928                 $LFS setdirstripe -c $c $DIR/$tdir ||
22929                         error "split -c $c $tdir failed"
22930                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22931                         mdt_hash="$mdt_hash,fixed"
22932                 elif [ $c -eq 1 ]; then
22933                         mdt_hash="none"
22934                 fi
22935                 wait_update $HOSTNAME \
22936                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22937                         error "dir merge not finished"
22938                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22939                         awk '/migrate/ {sum += $2} END { print sum }')
22940                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22941                 # delta is around total_files/stripe_count
22942                 (( delta < 200 / c + 4 )) ||
22943                         error "$delta files migrated >= $((200 / c + 4))"
22944         done
22945 }
22946 run_test 230p "dir merge"
22947
22948 test_230q() {
22949         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22950         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22951                 skip "Need MDS version at least 2.13.52"
22952
22953         local mdts=$(comma_list $(mdts_nodes))
22954         local saved_threshold=$(do_facet mds1 \
22955                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22956         local saved_delta=$(do_facet mds1 \
22957                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22958         local threshold=100
22959         local delta=2
22960         local total=0
22961         local stripe_count=0
22962         local stripe_index
22963         local nr_files
22964         local create
22965
22966         # test with fewer files on ZFS
22967         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22968
22969         stack_trap "do_nodes $mdts $LCTL set_param \
22970                     mdt.*.dir_split_count=$saved_threshold"
22971         stack_trap "do_nodes $mdts $LCTL set_param \
22972                     mdt.*.dir_split_delta=$saved_delta"
22973         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22974         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22975         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22976         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22977         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22978         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22979
22980         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22981         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22982
22983         create=$((threshold * 3 / 2))
22984         while [ $stripe_count -lt $MDSCOUNT ]; do
22985                 createmany -m $DIR/$tdir/f $total $create ||
22986                         error "create sub files failed"
22987                 stat $DIR/$tdir > /dev/null
22988                 total=$((total + create))
22989                 stripe_count=$((stripe_count + delta))
22990                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22991
22992                 wait_update $HOSTNAME \
22993                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22994                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22995
22996                 wait_update $HOSTNAME \
22997                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22998                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22999
23000                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
23001                 echo "$nr_files/$total files on MDT$stripe_index after split"
23002                 # allow 10% margin of imbalance with crush hash
23003                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
23004                         error "$nr_files files on MDT$stripe_index after split"
23005
23006                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
23007                 [ $nr_files -eq $total ] ||
23008                         error "total sub files $nr_files != $total"
23009         done
23010
23011         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
23012
23013         echo "fixed layout directory won't auto split"
23014         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
23015         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
23016                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
23017         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
23018                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
23019 }
23020 run_test 230q "dir auto split"
23021
23022 test_230r() {
23023         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
23024         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
23025         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
23026                 skip "Need MDS version at least 2.13.54"
23027
23028         # maximum amount of local locks:
23029         # parent striped dir - 2 locks
23030         # new stripe in parent to migrate to - 1 lock
23031         # source and target - 2 locks
23032         # Total 5 locks for regular file
23033         mkdir -p $DIR/$tdir
23034         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
23035         touch $DIR/$tdir/dir1/eee
23036
23037         # create 4 hardlink for 4 more locks
23038         # Total: 9 locks > RS_MAX_LOCKS (8)
23039         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
23040         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
23041         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
23042         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
23043         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
23044         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
23045         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
23046         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
23047
23048         cancel_lru_locks mdc
23049
23050         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
23051                 error "migrate dir fails"
23052
23053         rm -rf $DIR/$tdir || error "rm dir failed after migration"
23054 }
23055 run_test 230r "migrate with too many local locks"
23056
23057 test_230s() {
23058         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
23059                 skip "Need MDS version at least 2.14.52"
23060
23061         local mdts=$(comma_list $(mdts_nodes))
23062         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
23063                                 mdt.*MDT0000.enable_dir_restripe)
23064
23065         stack_trap "do_nodes $mdts $LCTL set_param \
23066                     mdt.*.enable_dir_restripe=$restripe_status"
23067
23068         local st
23069         for st in 0 1; do
23070                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
23071                 test_mkdir $DIR/$tdir
23072                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
23073                         error "$LFS mkdir should return EEXIST if target exists"
23074                 rmdir $DIR/$tdir
23075         done
23076 }
23077 run_test 230s "lfs mkdir should return -EEXIST if target exists"
23078
23079 test_230t()
23080 {
23081         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23082         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
23083                 skip "Need MDS version at least 2.14.50"
23084
23085         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
23086         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
23087         $LFS project -p 1 -s $DIR/$tdir ||
23088                 error "set $tdir project id failed"
23089         $LFS project -p 2 -s $DIR/$tdir/subdir ||
23090                 error "set subdir project id failed"
23091         local pbefore="$($LFS project -d $DIR/$tdir)"
23092         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
23093         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
23094
23095         local pafter="$($LFS project -d $DIR/$tdir)"
23096         local safter="$($LFS project -d $DIR/$tdir/subdir)"
23097         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
23098         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
23099
23100         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
23101                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
23102
23103         # check rename works, even if source parent projid differs (LU-17016)
23104         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
23105         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
23106
23107         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
23108         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
23109                 error "subdir failed rename for different source parent projid"
23110         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
23111
23112         [[ "$fid_before" == "$fid_after" ]] ||
23113                 error "fid before '$fid_before' != after '$fid_after'"
23114 }
23115 run_test 230t "migrate directory with project ID set"
23116
23117 test_230u()
23118 {
23119         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23120         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23121                 skip "Need MDS version at least 2.14.53"
23122
23123         local count
23124
23125         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23126         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23127         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
23128         for i in $(seq 0 $((MDSCOUNT - 1))); do
23129                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23130                 echo "$count dirs migrated to MDT$i"
23131         done
23132         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23133         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
23134 }
23135 run_test 230u "migrate directory by QOS"
23136
23137 test_230v()
23138 {
23139         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23140         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23141                 skip "Need MDS version at least 2.14.53"
23142
23143         local count
23144
23145         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23146         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23147         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23148         for i in $(seq 0 $((MDSCOUNT - 1))); do
23149                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23150                 echo "$count subdirs migrated to MDT$i"
23151                 (( i == 3 )) && (( count > 0 )) &&
23152                         error "subdir shouldn't be migrated to MDT3"
23153         done
23154         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23155         (( count == 3 )) || error "dirs migrated to $count MDTs"
23156 }
23157 run_test 230v "subdir migrated to the MDT where its parent is located"
23158
23159 test_230w() {
23160         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23161         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23162                 skip "Need MDS version at least 2.15.0"
23163
23164         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23165         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23166         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23167
23168         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23169                 error "migrate failed"
23170
23171         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23172                 error "$tdir stripe count mismatch"
23173
23174         for i in $(seq 0 9); do
23175                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23176                         error "d$i is striped"
23177         done
23178 }
23179 run_test 230w "non-recursive mode dir migration"
23180
23181 test_230x() {
23182         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23183         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23184                 skip "Need MDS version at least 2.15.0"
23185
23186         mkdir -p $DIR/$tdir || error "mkdir failed"
23187         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23188
23189         local mdt_name=$(mdtname_from_index 0)
23190         local low=$(do_facet mds2 $LCTL get_param -n \
23191                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23192         local high=$(do_facet mds2 $LCTL get_param -n \
23193                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23194         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23195         local maxage=$(do_facet mds2 $LCTL get_param -n \
23196                 osp.*$mdt_name-osp-MDT0001.maxage)
23197
23198         stack_trap "do_facet mds2 $LCTL set_param -n \
23199                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23200                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23201         stack_trap "do_facet mds2 $LCTL set_param -n \
23202                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23203
23204         do_facet mds2 $LCTL set_param -n \
23205                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23206         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23207         sleep 4
23208         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23209                 error "migrate $tdir should fail"
23210
23211         do_facet mds2 $LCTL set_param -n \
23212                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23213         do_facet mds2 $LCTL set_param -n \
23214                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23215         sleep 4
23216         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23217                 error "migrate failed"
23218         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23219                 error "$tdir stripe count mismatch"
23220 }
23221 run_test 230x "dir migration check space"
23222
23223 test_230y() {
23224         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23225         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23226                 skip "Need MDS version at least 2.15.55.45"
23227
23228         local pid
23229
23230         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23231         $LFS getdirstripe $DIR/$tdir
23232         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23233         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23234         pid=$!
23235         sleep 1
23236
23237         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23238         do_facet mds2 lctl set_param fail_loc=0x1802
23239
23240         wait $pid
23241         do_facet mds2 lctl set_param fail_loc=0
23242         $LFS getdirstripe $DIR/$tdir
23243         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23244         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23245 }
23246 run_test 230y "unlink dir with bad hash type"
23247
23248 test_230z() {
23249         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23250         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23251                 skip "Need MDS version at least 2.15.55.45"
23252
23253         local pid
23254
23255         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23256         $LFS getdirstripe $DIR/$tdir
23257         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23258         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23259         pid=$!
23260         sleep 1
23261
23262         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23263         do_facet mds2 lctl set_param fail_loc=0x1802
23264
23265         wait $pid
23266         do_facet mds2 lctl set_param fail_loc=0
23267         $LFS getdirstripe $DIR/$tdir
23268
23269         # resume migration
23270         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23271                 error "resume migration failed"
23272         $LFS getdirstripe $DIR/$tdir
23273         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23274                 error "migration is not finished"
23275 }
23276 run_test 230z "resume dir migration with bad hash type"
23277
23278 test_231a()
23279 {
23280         # For simplicity this test assumes that max_pages_per_rpc
23281         # is the same across all OSCs
23282         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23283         local bulk_size=$((max_pages * PAGE_SIZE))
23284         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23285                                        head -n 1)
23286
23287         mkdir -p $DIR/$tdir
23288         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23289                 error "failed to set stripe with -S ${brw_size}M option"
23290         stack_trap "rm -rf $DIR/$tdir"
23291
23292         # clear the OSC stats
23293         $LCTL set_param osc.*.stats=0 &>/dev/null
23294         stop_writeback
23295
23296         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23297         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23298                 oflag=direct &>/dev/null || error "dd failed"
23299
23300         sync; sleep 1; sync # just to be safe
23301         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23302         if [ x$nrpcs != "x1" ]; then
23303                 $LCTL get_param osc.*.stats
23304                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23305         fi
23306
23307         start_writeback
23308         # Drop the OSC cache, otherwise we will read from it
23309         cancel_lru_locks osc
23310
23311         # clear the OSC stats
23312         $LCTL set_param osc.*.stats=0 &>/dev/null
23313
23314         # Client reads $bulk_size.
23315         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23316                 iflag=direct &>/dev/null || error "dd failed"
23317
23318         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23319         if [ x$nrpcs != "x1" ]; then
23320                 $LCTL get_param osc.*.stats
23321                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23322         fi
23323 }
23324 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23325
23326 test_231b() {
23327         mkdir -p $DIR/$tdir
23328         stack_trap "rm -rf $DIR/$tdir"
23329         local i
23330         for i in {0..1023}; do
23331                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23332                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23333                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23334         done
23335         sync
23336 }
23337 run_test 231b "must not assert on fully utilized OST request buffer"
23338
23339 test_232a() {
23340         mkdir -p $DIR/$tdir
23341         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23342
23343         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23344         do_facet ost1 $LCTL set_param fail_loc=0x31c
23345
23346         # ignore dd failure
23347         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23348         stack_trap "rm -f $DIR/$tdir/$tfile"
23349
23350         do_facet ost1 $LCTL set_param fail_loc=0
23351         umount_client $MOUNT || error "umount failed"
23352         mount_client $MOUNT || error "mount failed"
23353         stop ost1 || error "cannot stop ost1"
23354         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23355 }
23356 run_test 232a "failed lock should not block umount"
23357
23358 test_232b() {
23359         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23360                 skip "Need MDS version at least 2.10.58"
23361
23362         mkdir -p $DIR/$tdir
23363         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23364         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23365         stack_trap "rm -f $DIR/$tdir/$tfile"
23366         sync
23367         cancel_lru_locks osc
23368
23369         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23370         do_facet ost1 $LCTL set_param fail_loc=0x31c
23371
23372         # ignore failure
23373         $LFS data_version $DIR/$tdir/$tfile || true
23374
23375         do_facet ost1 $LCTL set_param fail_loc=0
23376         umount_client $MOUNT || error "umount failed"
23377         mount_client $MOUNT || error "mount failed"
23378         stop ost1 || error "cannot stop ost1"
23379         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23380 }
23381 run_test 232b "failed data version lock should not block umount"
23382
23383 test_233a() {
23384         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23385                 skip "Need MDS version at least 2.3.64"
23386         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23387
23388         local fid=$($LFS path2fid $MOUNT)
23389
23390         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23391                 error "cannot access $MOUNT using its FID '$fid'"
23392 }
23393 run_test 233a "checking that OBF of the FS root succeeds"
23394
23395 test_233b() {
23396         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23397                 skip "Need MDS version at least 2.5.90"
23398         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23399
23400         local fid=$($LFS path2fid $MOUNT/.lustre)
23401
23402         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23403                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23404
23405         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23406         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23407                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23408 }
23409 run_test 233b "checking that OBF of the FS .lustre succeeds"
23410
23411 test_234() {
23412         local p="$TMP/sanityN-$TESTNAME.parameters"
23413         save_lustre_params client "llite.*.xattr_cache" > $p
23414         lctl set_param llite.*.xattr_cache 1 ||
23415                 skip_env "xattr cache is not supported"
23416
23417         mkdir -p $DIR/$tdir || error "mkdir failed"
23418         touch $DIR/$tdir/$tfile || error "touch failed"
23419         # OBD_FAIL_LLITE_XATTR_ENOMEM
23420         $LCTL set_param fail_loc=0x1405
23421         getfattr -n user.attr $DIR/$tdir/$tfile &&
23422                 error "getfattr should have failed with ENOMEM"
23423         $LCTL set_param fail_loc=0x0
23424         rm -rf $DIR/$tdir
23425
23426         restore_lustre_params < $p
23427         rm -f $p
23428 }
23429 run_test 234 "xattr cache should not crash on ENOMEM"
23430
23431 test_235() {
23432         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23433                 skip "Need MDS version at least 2.4.52"
23434
23435         flock_deadlock $DIR/$tfile
23436         local RC=$?
23437         case $RC in
23438                 0)
23439                 ;;
23440                 124) error "process hangs on a deadlock"
23441                 ;;
23442                 *) error "error executing flock_deadlock $DIR/$tfile"
23443                 ;;
23444         esac
23445 }
23446 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23447
23448 #LU-2935
23449 test_236() {
23450         check_swap_layouts_support
23451
23452         local ref1=/etc/passwd
23453         local ref2=/etc/group
23454         local file1=$DIR/$tdir/f1
23455         local file2=$DIR/$tdir/f2
23456
23457         test_mkdir -c1 $DIR/$tdir
23458         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23459         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23460         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23461         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23462         local fd=$(free_fd)
23463         local cmd="exec $fd<>$file2"
23464         eval $cmd
23465         rm $file2
23466         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23467                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23468         cmd="exec $fd>&-"
23469         eval $cmd
23470         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23471
23472         #cleanup
23473         rm -rf $DIR/$tdir
23474 }
23475 run_test 236 "Layout swap on open unlinked file"
23476
23477 # LU-4659 linkea consistency
23478 test_238() {
23479         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23480                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23481                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23482                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23483
23484         touch $DIR/$tfile
23485         ln $DIR/$tfile $DIR/$tfile.lnk
23486         touch $DIR/$tfile.new
23487         mv $DIR/$tfile.new $DIR/$tfile
23488         local fid1=$($LFS path2fid $DIR/$tfile)
23489         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23490         local path1=$($LFS fid2path $FSNAME "$fid1")
23491         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23492         local path2=$($LFS fid2path $FSNAME "$fid2")
23493         [ $tfile.lnk == $path2 ] ||
23494                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23495         rm -f $DIR/$tfile*
23496 }
23497 run_test 238 "Verify linkea consistency"
23498
23499 test_239A() { # was test_239
23500         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23501                 skip "Need MDS version at least 2.5.60"
23502
23503         local list=$(comma_list $(mdts_nodes))
23504
23505         mkdir -p $DIR/$tdir
23506         createmany -o $DIR/$tdir/f- 5000
23507         unlinkmany $DIR/$tdir/f- 5000
23508         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23509                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23510         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23511                         osp.*MDT*.sync_in_flight" | calc_sum)
23512         [ "$changes" -eq 0 ] || error "$changes not synced"
23513 }
23514 run_test 239A "osp_sync test"
23515
23516 test_239a() { #LU-5297
23517         remote_mds_nodsh && skip "remote MDS with nodsh"
23518
23519         touch $DIR/$tfile
23520         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23521         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23522         chgrp $RUNAS_GID $DIR/$tfile
23523         wait_delete_completed
23524 }
23525 run_test 239a "process invalid osp sync record correctly"
23526
23527 test_239b() { #LU-5297
23528         remote_mds_nodsh && skip "remote MDS with nodsh"
23529
23530         touch $DIR/$tfile1
23531         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23532         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23533         chgrp $RUNAS_GID $DIR/$tfile1
23534         wait_delete_completed
23535         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23536         touch $DIR/$tfile2
23537         chgrp $RUNAS_GID $DIR/$tfile2
23538         wait_delete_completed
23539 }
23540 run_test 239b "process osp sync record with ENOMEM error correctly"
23541
23542 test_240() {
23543         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23544         remote_mds_nodsh && skip "remote MDS with nodsh"
23545
23546         mkdir -p $DIR/$tdir
23547
23548         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23549                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23550         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23551                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23552
23553         umount_client $MOUNT || error "umount failed"
23554         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23555         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23556         mount_client $MOUNT || error "failed to mount client"
23557
23558         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23559         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23560 }
23561 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23562
23563 test_241_bio() {
23564         local count=$1
23565         local bsize=$2
23566
23567         for LOOP in $(seq $count); do
23568                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23569                 cancel_lru_locks $OSC || true
23570         done
23571 }
23572
23573 test_241_dio() {
23574         local count=$1
23575         local bsize=$2
23576
23577         for LOOP in $(seq $1); do
23578                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23579                         2>/dev/null
23580         done
23581 }
23582
23583 test_241a() { # was test_241
23584         local bsize=$PAGE_SIZE
23585
23586         (( bsize < 40960 )) && bsize=40960
23587         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23588         ls -la $DIR/$tfile
23589         cancel_lru_locks $OSC
23590         test_241_bio 1000 $bsize &
23591         PID=$!
23592         test_241_dio 1000 $bsize
23593         wait $PID
23594 }
23595 run_test 241a "bio vs dio"
23596
23597 test_241b() {
23598         local bsize=$PAGE_SIZE
23599
23600         (( bsize < 40960 )) && bsize=40960
23601         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23602         ls -la $DIR/$tfile
23603         test_241_dio 1000 $bsize &
23604         PID=$!
23605         test_241_dio 1000 $bsize
23606         wait $PID
23607 }
23608 run_test 241b "dio vs dio"
23609
23610 test_242() {
23611         remote_mds_nodsh && skip "remote MDS with nodsh"
23612
23613         mkdir_on_mdt0 $DIR/$tdir
23614         touch $DIR/$tdir/$tfile
23615
23616         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23617         do_facet mds1 lctl set_param fail_loc=0x105
23618         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23619
23620         do_facet mds1 lctl set_param fail_loc=0
23621         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23622 }
23623 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23624
23625 test_243()
23626 {
23627         test_mkdir $DIR/$tdir
23628         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23629 }
23630 run_test 243 "various group lock tests"
23631
23632 test_244a()
23633 {
23634         test_mkdir $DIR/$tdir
23635         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23636         sendfile_grouplock $DIR/$tdir/$tfile || \
23637                 error "sendfile+grouplock failed"
23638         rm -rf $DIR/$tdir
23639 }
23640 run_test 244a "sendfile with group lock tests"
23641
23642 test_244b()
23643 {
23644         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23645
23646         local threads=50
23647         local size=$((1024*1024))
23648
23649         test_mkdir $DIR/$tdir
23650         for i in $(seq 1 $threads); do
23651                 local file=$DIR/$tdir/file_$((i / 10))
23652                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23653                 local pids[$i]=$!
23654         done
23655         for i in $(seq 1 $threads); do
23656                 wait ${pids[$i]}
23657         done
23658 }
23659 run_test 244b "multi-threaded write with group lock"
23660
23661 test_245a() {
23662         local flagname="multi_mod_rpcs"
23663         local connect_data_name="max_mod_rpcs"
23664         local out
23665
23666         # check if multiple modify RPCs flag is set
23667         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23668                 grep "connect_flags:")
23669         echo "$out"
23670
23671         echo "$out" | grep -qw $flagname
23672         if [ $? -ne 0 ]; then
23673                 echo "connect flag $flagname is not set"
23674                 return
23675         fi
23676
23677         # check if multiple modify RPCs data is set
23678         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23679         echo "$out"
23680
23681         echo "$out" | grep -qw $connect_data_name ||
23682                 error "import should have connect data $connect_data_name"
23683 }
23684 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23685
23686 test_245b() {
23687         local flagname="multi_mod_rpcs"
23688         local connect_data_name="max_mod_rpcs"
23689         local out
23690
23691         remote_mds_nodsh && skip "remote MDS with nodsh"
23692         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23693
23694         # check if multiple modify RPCs flag is set
23695         out=$(do_facet mds1 \
23696               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23697               grep "connect_flags:")
23698         echo "$out"
23699
23700         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23701
23702         # check if multiple modify RPCs data is set
23703         out=$(do_facet mds1 \
23704               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23705
23706         [[ "$out" =~ $connect_data_name ]] ||
23707                 {
23708                         echo "$out"
23709                         error "missing connect data $connect_data_name"
23710                 }
23711 }
23712 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23713
23714 cleanup_247() {
23715         local submount=$1
23716
23717         trap 0
23718         umount_client $submount
23719         rmdir $submount
23720 }
23721
23722 test_247a() {
23723         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23724                 grep -q subtree ||
23725                 skip_env "Fileset feature is not supported"
23726
23727         local submount=${MOUNT}_$tdir
23728
23729         mkdir $MOUNT/$tdir
23730         mkdir -p $submount || error "mkdir $submount failed"
23731         FILESET="$FILESET/$tdir" mount_client $submount ||
23732                 error "mount $submount failed"
23733         trap "cleanup_247 $submount" EXIT
23734         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23735         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23736                 error "read $MOUNT/$tdir/$tfile failed"
23737         cleanup_247 $submount
23738 }
23739 run_test 247a "mount subdir as fileset"
23740
23741 test_247b() {
23742         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23743                 skip_env "Fileset feature is not supported"
23744
23745         local submount=${MOUNT}_$tdir
23746
23747         rm -rf $MOUNT/$tdir
23748         mkdir -p $submount || error "mkdir $submount failed"
23749         SKIP_FILESET=1
23750         FILESET="$FILESET/$tdir" mount_client $submount &&
23751                 error "mount $submount should fail"
23752         rmdir $submount
23753 }
23754 run_test 247b "mount subdir that dose not exist"
23755
23756 test_247c() {
23757         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23758                 skip_env "Fileset feature is not supported"
23759
23760         local submount=${MOUNT}_$tdir
23761
23762         mkdir -p $MOUNT/$tdir/dir1
23763         mkdir -p $submount || error "mkdir $submount failed"
23764         trap "cleanup_247 $submount" EXIT
23765         FILESET="$FILESET/$tdir" mount_client $submount ||
23766                 error "mount $submount failed"
23767         local fid=$($LFS path2fid $MOUNT/)
23768         $LFS fid2path $submount $fid && error "fid2path should fail"
23769         cleanup_247 $submount
23770 }
23771 run_test 247c "running fid2path outside subdirectory root"
23772
23773 test_247d() {
23774         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23775                 skip "Fileset feature is not supported"
23776
23777         local submount=${MOUNT}_$tdir
23778
23779         mkdir -p $MOUNT/$tdir/dir1
23780         mkdir -p $submount || error "mkdir $submount failed"
23781         FILESET="$FILESET/$tdir" mount_client $submount ||
23782                 error "mount $submount failed"
23783         trap "cleanup_247 $submount" EXIT
23784
23785         local td=$submount/dir1
23786         local fid=$($LFS path2fid $td)
23787         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23788
23789         # check that we get the same pathname back
23790         local rootpath
23791         local found
23792         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23793                 echo "$rootpath $fid"
23794                 found=$($LFS fid2path $rootpath "$fid")
23795                 [ -n "$found" ] || error "fid2path should succeed"
23796                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23797         done
23798         # check wrong root path format
23799         rootpath=$submount"_wrong"
23800         found=$($LFS fid2path $rootpath "$fid")
23801         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23802
23803         cleanup_247 $submount
23804 }
23805 run_test 247d "running fid2path inside subdirectory root"
23806
23807 # LU-8037
23808 test_247e() {
23809         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23810                 grep -q subtree ||
23811                 skip "Fileset feature is not supported"
23812
23813         local submount=${MOUNT}_$tdir
23814
23815         mkdir $MOUNT/$tdir
23816         mkdir -p $submount || error "mkdir $submount failed"
23817         FILESET="$FILESET/.." mount_client $submount &&
23818                 error "mount $submount should fail"
23819         rmdir $submount
23820 }
23821 run_test 247e "mount .. as fileset"
23822
23823 test_247f() {
23824         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23825         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23826                 skip "Need at least version 2.14.50.162"
23827         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23828                 skip "Fileset feature is not supported"
23829
23830         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23831         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23832                 error "mkdir remote failed"
23833         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23834                 error "mkdir remote/subdir failed"
23835         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23836                 error "mkdir striped failed"
23837         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23838
23839         local submount=${MOUNT}_$tdir
23840
23841         mkdir -p $submount || error "mkdir $submount failed"
23842         stack_trap "rmdir $submount"
23843
23844         local dir
23845         local fileset=$FILESET
23846         local mdts=$(comma_list $(mdts_nodes))
23847
23848         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23849         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23850                 $tdir/striped/subdir $tdir/striped/.; do
23851                 FILESET="$fileset/$dir" mount_client $submount ||
23852                         error "mount $dir failed"
23853                 umount_client $submount
23854         done
23855 }
23856 run_test 247f "mount striped or remote directory as fileset"
23857
23858 test_subdir_mount_lock()
23859 {
23860         local testdir=$1
23861         local submount=${MOUNT}_$(basename $testdir)
23862
23863         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23864
23865         mkdir -p $submount || error "mkdir $submount failed"
23866         stack_trap "rmdir $submount"
23867
23868         FILESET="$fileset/$testdir" mount_client $submount ||
23869                 error "mount $FILESET failed"
23870         stack_trap "umount $submount"
23871
23872         local mdts=$(comma_list $(mdts_nodes))
23873
23874         local nrpcs
23875
23876         stat $submount > /dev/null || error "stat $submount failed"
23877         cancel_lru_locks $MDC
23878         stat $submount > /dev/null || error "stat $submount failed"
23879         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23880         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23881         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23882         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23883                 awk '/getattr/ {sum += $2} END {print sum}')
23884
23885         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23886 }
23887
23888 test_247g() {
23889         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23890
23891         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23892                 error "mkdir $tdir failed"
23893         test_subdir_mount_lock $tdir
23894 }
23895 run_test 247g "striped directory submount revalidate ROOT from cache"
23896
23897 test_247h() {
23898         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23899         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23900                 skip "Need MDS version at least 2.15.51"
23901
23902         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23903         test_subdir_mount_lock $tdir
23904         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23905         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23906                 error "mkdir $tdir.1 failed"
23907         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23908 }
23909 run_test 247h "remote directory submount revalidate ROOT from cache"
23910
23911 test_248a() {
23912         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23913         [ -z "$fast_read_sav" ] && skip "no fast read support"
23914
23915         # create a large file for fast read verification
23916         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23917
23918         # make sure the file is created correctly
23919         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23920                 { rm -f $DIR/$tfile; skip "file creation error"; }
23921
23922         echo "Test 1: verify that fast read is 4 times faster on cache read"
23923
23924         # small read with fast read enabled
23925         $LCTL set_param -n llite.*.fast_read=1
23926         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23927                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23928                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23929         # small read with fast read disabled
23930         $LCTL set_param -n llite.*.fast_read=0
23931         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23932                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23933                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23934
23935         # verify that fast read is 4 times faster for cache read
23936         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23937                 error_not_in_vm "fast read was not 4 times faster: " \
23938                            "$t_fast vs $t_slow"
23939
23940         echo "Test 2: verify the performance between big and small read"
23941         $LCTL set_param -n llite.*.fast_read=1
23942
23943         # 1k non-cache read
23944         cancel_lru_locks osc
23945         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23946                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23947                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23948
23949         # 1M non-cache read
23950         cancel_lru_locks osc
23951         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23952                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23953                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23954
23955         # verify that big IO is not 4 times faster than small IO
23956         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23957                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23958
23959         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23960         rm -f $DIR/$tfile
23961 }
23962 run_test 248a "fast read verification"
23963
23964 test_248b() {
23965         # Default short_io_bytes=16384, try both smaller and larger sizes.
23966         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23967         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23968         echo "bs=53248 count=113 normal buffered write"
23969         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23970                 error "dd of initial data file failed"
23971         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23972
23973         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23974         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23975                 error "dd with sync normal writes failed"
23976         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23977
23978         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23979         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23980                 error "dd with sync small writes failed"
23981         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23982
23983         cancel_lru_locks osc
23984
23985         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23986         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23987         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23988         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23989                 iflag=direct || error "dd with O_DIRECT small read failed"
23990         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23991         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23992                 error "compare $TMP/$tfile.1 failed"
23993
23994         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23995         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23996
23997         # just to see what the maximum tunable value is, and test parsing
23998         echo "test invalid parameter 2MB"
23999         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
24000                 error "too-large short_io_bytes allowed"
24001         echo "test maximum parameter 512KB"
24002         # if we can set a larger short_io_bytes, run test regardless of version
24003         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
24004                 # older clients may not allow setting it this large, that's OK
24005                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
24006                         skip "Need at least client version 2.13.50"
24007                 error "medium short_io_bytes failed"
24008         fi
24009         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
24010         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
24011
24012         echo "test large parameter 64KB"
24013         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
24014         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
24015
24016         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
24017         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
24018                 error "dd with sync large writes failed"
24019         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
24020
24021         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
24022         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
24023         num=$((113 * 4096 / PAGE_SIZE))
24024         echo "bs=$size count=$num oflag=direct large write $tfile.3"
24025         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
24026                 error "dd with O_DIRECT large writes failed"
24027         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
24028                 error "compare $DIR/$tfile.3 failed"
24029
24030         cancel_lru_locks osc
24031
24032         echo "bs=$size count=$num iflag=direct large read $tfile.2"
24033         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
24034                 error "dd with O_DIRECT large read failed"
24035         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
24036                 error "compare $TMP/$tfile.2 failed"
24037
24038         echo "bs=$size count=$num iflag=direct large read $tfile.3"
24039         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
24040                 error "dd with O_DIRECT large read failed"
24041         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
24042                 error "compare $TMP/$tfile.3 failed"
24043 }
24044 run_test 248b "test short_io read and write for both small and large sizes"
24045
24046 test_248c() {
24047         $LCTL set_param llite.*.read_ahead_stats=c
24048         # This test compares whole file readahead to non-whole file readahead
24049         # The performance should be consistently slightly faster for whole file,
24050         # and the bug caused whole file readahead to be 80-100x slower, but to
24051         # account for possible test system lag, we require whole file to be
24052         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
24053         # test
24054         local time1
24055         local time2
24056         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
24057         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
24058         counter=0
24059
24060         while [ $counter -lt 3 ]; do
24061                 # Increment the counter
24062                 ((counter++))
24063
24064                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
24065                 rm -f $DIR/$tfile
24066                 touch $DIR/$tfile || error "(0) failed to create file"
24067                 # 64 MiB
24068                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
24069                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
24070                 echo "whole file readahead of 64 MiB took $time1 seconds"
24071                 $LCTL get_param llite.*.read_ahead_stats
24072
24073                 $LCTL set_param llite.*.read_ahead_stats=c
24074                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
24075                 rm -f $DIR/$tfile
24076                 touch $DIR/$tfile || error "(2) failed to create file"
24077                 # 64 MiB
24078                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
24079                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
24080                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
24081                 $LCTL get_param llite.*.read_ahead_stats
24082
24083                 # Check if time1 is not more than 1.5 times2
24084                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
24085
24086                 if [[ $timecheck -eq 1 ]]; then
24087                         echo "Test passed on attempt $counter"
24088                         # Exit the loop
24089                         counter=4
24090                 else
24091                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
24092                 fi
24093         done
24094         if [ $counter -eq 3 ]; then
24095                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
24096         fi
24097
24098 }
24099 run_test 248c "verify whole file read behavior"
24100
24101 test_249() { # LU-7890
24102         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
24103                 skip "Need at least version 2.8.54"
24104
24105         rm -f $DIR/$tfile
24106         $LFS setstripe -c 1 $DIR/$tfile
24107         # Offset 2T == 4k * 512M
24108         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
24109                 error "dd to 2T offset failed"
24110 }
24111 run_test 249 "Write above 2T file size"
24112
24113 test_250() {
24114         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
24115          && skip "no 16TB file size limit on ZFS"
24116
24117         $LFS setstripe -c 1 $DIR/$tfile
24118         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
24119         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
24120         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
24121         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
24122                 conv=notrunc,fsync && error "append succeeded"
24123         return 0
24124 }
24125 run_test 250 "Write above 16T limit"
24126
24127 test_251a() {
24128         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
24129
24130         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
24131         #Skip once - writing the first stripe will succeed
24132         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24133         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
24134                 error "short write happened"
24135
24136         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24137         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
24138                 error "short read happened"
24139
24140         rm -f $DIR/$tfile
24141 }
24142 run_test 251a "Handling short read and write correctly"
24143
24144 test_251b() {
24145         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24146                 error "write $tfile failed"
24147
24148         sleep 2 && echo 12345 >> $DIR/$tfile &
24149
24150         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24151         $LCTL set_param fail_loc=0x1431 fail_val=5
24152         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24153         # 5 seconds, read 10 bytes, the short read should
24154         # report:
24155         #                start ->+ read_len -> offset_after_read read_count
24156         #     short read: 4096 ->+ 10 -> 4096 0
24157         # not:
24158         #     short read: 4096 ->+ 10 -> 4102 0
24159         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24160                         awk '/short read/ { print $7 }')
24161         (( off == 4096 )) ||
24162                 error "short read should set offset at 4096, not $off"
24163 }
24164 run_test 251b "short read restore offset correctly"
24165
24166 test_252() {
24167         remote_mds_nodsh && skip "remote MDS with nodsh"
24168         remote_ost_nodsh && skip "remote OST with nodsh"
24169         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24170                 skip_env "ldiskfs only test"
24171         fi
24172
24173         local tgt
24174         local dev
24175         local out
24176         local uuid
24177         local num
24178         local gen
24179
24180         # check lr_reader on OST0000
24181         tgt=ost1
24182         dev=$(facet_device $tgt)
24183         out=$(do_facet $tgt $LR_READER $dev)
24184         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24185         echo "$out"
24186         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24187         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24188                 error "Invalid uuid returned by $LR_READER on target $tgt"
24189         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24190
24191         # check lr_reader -c on MDT0000
24192         tgt=mds1
24193         dev=$(facet_device $tgt)
24194         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24195                 skip "$LR_READER does not support additional options"
24196         fi
24197         out=$(do_facet $tgt $LR_READER -c $dev)
24198         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24199         echo "$out"
24200         num=$(echo "$out" | grep -c "mdtlov")
24201         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24202                 error "Invalid number of mdtlov clients returned by $LR_READER"
24203         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24204
24205         # check lr_reader -cr on MDT0000
24206         out=$(do_facet $tgt $LR_READER -cr $dev)
24207         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24208         echo "$out"
24209         echo "$out" | grep -q "^reply_data:$" ||
24210                 error "$LR_READER should have returned 'reply_data' section"
24211         num=$(echo "$out" | grep -c "client_generation")
24212         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24213 }
24214 run_test 252 "check lr_reader tool"
24215
24216 test_253() {
24217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24218         remote_mds_nodsh && skip "remote MDS with nodsh"
24219         remote_mgs_nodsh && skip "remote MGS with nodsh"
24220         check_set_fallocate_or_skip
24221
24222         local ostidx=0
24223         local rc=0
24224         local ost_name=$(ostname_from_index $ostidx)
24225
24226         # on the mdt's osc
24227         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24228         do_facet $SINGLEMDS $LCTL get_param -n \
24229                 osp.$mdtosc_proc1.reserved_mb_high ||
24230                 skip  "remote MDS does not support reserved_mb_high"
24231
24232         rm -rf $DIR/$tdir
24233         wait_mds_ost_sync
24234         wait_delete_completed
24235         mkdir $DIR/$tdir
24236         stack_trap "rm -rf $DIR/$tdir"
24237
24238         pool_add $TESTNAME || error "Pool creation failed"
24239         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24240
24241         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24242                 error "Setstripe failed"
24243
24244         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24245
24246         local wms=$(ost_watermarks_get $ostidx)
24247
24248         ost_watermarks_set $ostidx 60 50
24249         stack_trap "ost_watermarks_set $ostidx $wms"
24250
24251         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24252         local size=$((free_kb * 1024))
24253
24254         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24255                 error "fallocate failed"
24256         sleep_maxage
24257
24258         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24259                         osp.$mdtosc_proc1.prealloc_status)
24260         echo "prealloc_status $oa_status"
24261
24262         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24263                 error "File creation should fail"
24264
24265         #object allocation was stopped, but we still able to append files
24266         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24267                 oflag=append || error "Append failed"
24268
24269         rm -f $DIR/$tdir/$tfile.0
24270         rm -f $DIR/$tdir/fill_ost$ostidx
24271
24272         wait_delete_completed
24273         sleep_maxage
24274
24275         for i in $(seq 10 12); do
24276                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24277                         2>/dev/null || error "File creation failed after rm"
24278         done
24279
24280         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24281                         osp.$mdtosc_proc1.prealloc_status)
24282         echo "prealloc_status $oa_status"
24283
24284         if (( oa_status != 0 )); then
24285                 error "Object allocation still disable after rm"
24286         fi
24287 }
24288 run_test 253 "Check object allocation limit"
24289
24290 test_254() {
24291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24292         remote_mds_nodsh && skip "remote MDS with nodsh"
24293
24294         local mdt=$(facet_svc $SINGLEMDS)
24295
24296         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24297                 skip "MDS does not support changelog_size"
24298
24299         local cl_user
24300
24301         changelog_register || error "changelog_register failed"
24302
24303         changelog_clear 0 || error "changelog_clear failed"
24304
24305         local size1=$(do_facet $SINGLEMDS \
24306                       $LCTL get_param -n mdd.$mdt.changelog_size)
24307         echo "Changelog size $size1"
24308
24309         rm -rf $DIR/$tdir
24310         $LFS mkdir -i 0 $DIR/$tdir
24311         # change something
24312         mkdir -p $DIR/$tdir/pics/2008/zachy
24313         touch $DIR/$tdir/pics/2008/zachy/timestamp
24314         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24315         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24316         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24317         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24318         rm $DIR/$tdir/pics/desktop.jpg
24319
24320         local size2=$(do_facet $SINGLEMDS \
24321                       $LCTL get_param -n mdd.$mdt.changelog_size)
24322         echo "Changelog size after work $size2"
24323
24324         (( $size2 > $size1 )) ||
24325                 error "new Changelog size=$size2 less than old size=$size1"
24326 }
24327 run_test 254 "Check changelog size"
24328
24329 ladvise_no_type()
24330 {
24331         local type=$1
24332         local file=$2
24333
24334         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24335                 awk -F: '{print $2}' | grep $type > /dev/null
24336         if [ $? -ne 0 ]; then
24337                 return 0
24338         fi
24339         return 1
24340 }
24341
24342 ladvise_no_ioctl()
24343 {
24344         local file=$1
24345
24346         lfs ladvise -a willread $file > /dev/null 2>&1
24347         if [ $? -eq 0 ]; then
24348                 return 1
24349         fi
24350
24351         lfs ladvise -a willread $file 2>&1 |
24352                 grep "Inappropriate ioctl for device" > /dev/null
24353         if [ $? -eq 0 ]; then
24354                 return 0
24355         fi
24356         return 1
24357 }
24358
24359 percent() {
24360         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24361 }
24362
24363 # run a random read IO workload
24364 # usage: random_read_iops <filename> <filesize> <iosize>
24365 random_read_iops() {
24366         local file=$1
24367         local fsize=$2
24368         local iosize=${3:-4096}
24369
24370         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24371                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24372 }
24373
24374 drop_file_oss_cache() {
24375         local file="$1"
24376         local nodes="$2"
24377
24378         $LFS ladvise -a dontneed $file 2>/dev/null ||
24379                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24380 }
24381
24382 ladvise_willread_performance()
24383 {
24384         local repeat=10
24385         local average_origin=0
24386         local average_cache=0
24387         local average_ladvise=0
24388
24389         for ((i = 1; i <= $repeat; i++)); do
24390                 echo "Iter $i/$repeat: reading without willread hint"
24391                 cancel_lru_locks osc
24392                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24393                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24394                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24395                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24396
24397                 cancel_lru_locks osc
24398                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24399                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24400                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24401
24402                 cancel_lru_locks osc
24403                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24404                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24405                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24406                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24407                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24408         done
24409         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24410         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24411         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24412
24413         speedup_cache=$(percent $average_cache $average_origin)
24414         speedup_ladvise=$(percent $average_ladvise $average_origin)
24415
24416         echo "Average uncached read: $average_origin"
24417         echo "Average speedup with OSS cached read:" \
24418                 "$average_cache = +$speedup_cache%"
24419         echo "Average speedup with ladvise willread:" \
24420                 "$average_ladvise = +$speedup_ladvise%"
24421
24422         local lowest_speedup=20
24423         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24424                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24425                      "got $speedup_cache%. Skipping ladvise willread check."
24426                 return 0
24427         fi
24428
24429         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24430         # it is still good to run until then to exercise 'ladvise willread'
24431         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24432                 [ "$ost1_FSTYPE" = "zfs" ] &&
24433                 echo "osd-zfs does not support dontneed or drop_caches" &&
24434                 return 0
24435
24436         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24437         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24438                 error_not_in_vm "Speedup with willread is less than " \
24439                         "$lowest_speedup%, got $speedup_ladvise%"
24440 }
24441
24442 test_255a() {
24443         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24444                 skip "lustre < 2.8.54 does not support ladvise "
24445         remote_ost_nodsh && skip "remote OST with nodsh"
24446
24447         stack_trap "rm -f $DIR/$tfile"
24448         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24449
24450         ladvise_no_type willread $DIR/$tfile &&
24451                 skip "willread ladvise is not supported"
24452
24453         ladvise_no_ioctl $DIR/$tfile &&
24454                 skip "ladvise ioctl is not supported"
24455
24456         local size_mb=100
24457         local size=$((size_mb * 1048576))
24458         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24459                 error "dd to $DIR/$tfile failed"
24460
24461         lfs ladvise -a willread $DIR/$tfile ||
24462                 error "Ladvise failed with no range argument"
24463
24464         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24465                 error "Ladvise failed with no -l or -e argument"
24466
24467         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24468                 error "Ladvise failed with only -e argument"
24469
24470         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24471                 error "Ladvise failed with only -l argument"
24472
24473         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24474                 error "End offset should not be smaller than start offset"
24475
24476         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24477                 error "End offset should not be equal to start offset"
24478
24479         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24480                 error "Ladvise failed with overflowing -s argument"
24481
24482         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24483                 error "Ladvise failed with overflowing -e argument"
24484
24485         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24486                 error "Ladvise failed with overflowing -l argument"
24487
24488         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24489                 error "Ladvise succeeded with conflicting -l and -e arguments"
24490
24491         echo "Synchronous ladvise should wait"
24492         local delay=8
24493 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24494         do_nodes $(comma_list $(osts_nodes)) \
24495                 $LCTL set_param fail_val=$delay fail_loc=0x237
24496         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24497                 $LCTL set_param fail_loc=0"
24498
24499         local start_ts=$SECONDS
24500         lfs ladvise -a willread $DIR/$tfile ||
24501                 error "Ladvise failed with no range argument"
24502         local end_ts=$SECONDS
24503         local inteval_ts=$((end_ts - start_ts))
24504
24505         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24506                 error "Synchronous advice didn't wait reply"
24507         fi
24508
24509         echo "Asynchronous ladvise shouldn't wait"
24510         local start_ts=$SECONDS
24511         lfs ladvise -a willread -b $DIR/$tfile ||
24512                 error "Ladvise failed with no range argument"
24513         local end_ts=$SECONDS
24514         local inteval_ts=$((end_ts - start_ts))
24515
24516         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24517                 error "Asynchronous advice blocked"
24518         fi
24519
24520         ladvise_willread_performance
24521 }
24522 run_test 255a "check 'lfs ladvise -a willread'"
24523
24524 facet_meminfo() {
24525         local facet=$1
24526         local info=$2
24527
24528         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24529 }
24530
24531 test_255b() {
24532         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24533                 skip "lustre < 2.8.54 does not support ladvise "
24534         remote_ost_nodsh && skip "remote OST with nodsh"
24535
24536         stack_trap "rm -f $DIR/$tfile"
24537         lfs setstripe -c 1 -i 0 $DIR/$tfile
24538
24539         ladvise_no_type dontneed $DIR/$tfile &&
24540                 skip "dontneed ladvise is not supported"
24541
24542         ladvise_no_ioctl $DIR/$tfile &&
24543                 skip "ladvise ioctl is not supported"
24544
24545         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24546                 [ "$ost1_FSTYPE" = "zfs" ] &&
24547                 skip "zfs-osd does not support 'ladvise dontneed'"
24548
24549         local size_mb=100
24550         local size=$((size_mb * 1048576))
24551         # In order to prevent disturbance of other processes, only check 3/4
24552         # of the memory usage
24553         local kibibytes=$((size_mb * 1024 * 3 / 4))
24554
24555         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24556                 error "dd to $DIR/$tfile failed"
24557
24558         #force write to complete before dropping OST cache & checking memory
24559         sync
24560
24561         local total=$(facet_meminfo ost1 MemTotal)
24562         echo "Total memory: $total KiB"
24563
24564         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24565         local before_read=$(facet_meminfo ost1 Cached)
24566         echo "Cache used before read: $before_read KiB"
24567
24568         lfs ladvise -a willread $DIR/$tfile ||
24569                 error "Ladvise willread failed"
24570         local after_read=$(facet_meminfo ost1 Cached)
24571         echo "Cache used after read: $after_read KiB"
24572
24573         lfs ladvise -a dontneed $DIR/$tfile ||
24574                 error "Ladvise dontneed again failed"
24575         local no_read=$(facet_meminfo ost1 Cached)
24576         echo "Cache used after dontneed ladvise: $no_read KiB"
24577
24578         if [ $total -lt $((before_read + kibibytes)) ]; then
24579                 echo "Memory is too small, abort checking"
24580                 return 0
24581         fi
24582
24583         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24584                 error "Ladvise willread should use more memory" \
24585                         "than $kibibytes KiB"
24586         fi
24587
24588         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24589                 error "Ladvise dontneed should release more memory" \
24590                         "than $kibibytes KiB"
24591         fi
24592 }
24593 run_test 255b "check 'lfs ladvise -a dontneed'"
24594
24595 test_255c() {
24596         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24597                 skip "lustre < 2.10.50 does not support lockahead"
24598
24599         local ost1_imp=$(get_osc_import_name client ost1)
24600         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24601                          cut -d'.' -f2)
24602         local count
24603         local new_count
24604         local difference
24605         local i
24606         local rc
24607
24608         test_mkdir -p $DIR/$tdir
24609         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24610
24611         #test 10 returns only success/failure
24612         i=10
24613         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24614         rc=$?
24615         if [ $rc -eq 255 ]; then
24616                 error "Ladvise test${i} failed, ${rc}"
24617         fi
24618
24619         #test 11 counts lock enqueue requests, all others count new locks
24620         i=11
24621         count=$(do_facet ost1 \
24622                 $LCTL get_param -n ost.OSS.ost.stats)
24623         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24624
24625         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24626         rc=$?
24627         if [ $rc -eq 255 ]; then
24628                 error "Ladvise test${i} failed, ${rc}"
24629         fi
24630
24631         new_count=$(do_facet ost1 \
24632                 $LCTL get_param -n ost.OSS.ost.stats)
24633         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24634                    awk '{ print $2 }')
24635
24636         difference="$((new_count - count))"
24637         if [ $difference -ne $rc ]; then
24638                 error "Ladvise test${i}, bad enqueue count, returned " \
24639                       "${rc}, actual ${difference}"
24640         fi
24641
24642         for i in $(seq 12 21); do
24643                 # If we do not do this, we run the risk of having too many
24644                 # locks and starting lock cancellation while we are checking
24645                 # lock counts.
24646                 cancel_lru_locks osc
24647
24648                 count=$($LCTL get_param -n \
24649                        ldlm.namespaces.$imp_name.lock_unused_count)
24650
24651                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24652                 rc=$?
24653                 if [ $rc -eq 255 ]; then
24654                         error "Ladvise test ${i} failed, ${rc}"
24655                 fi
24656
24657                 new_count=$($LCTL get_param -n \
24658                        ldlm.namespaces.$imp_name.lock_unused_count)
24659                 difference="$((new_count - count))"
24660
24661                 # Test 15 output is divided by 100 to map down to valid return
24662                 if [ $i -eq 15 ]; then
24663                         rc="$((rc * 100))"
24664                 fi
24665
24666                 if [ $difference -ne $rc ]; then
24667                         error "Ladvise test ${i}, bad lock count, returned " \
24668                               "${rc}, actual ${difference}"
24669                 fi
24670         done
24671
24672         #test 22 returns only success/failure
24673         i=22
24674         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24675         rc=$?
24676         if [ $rc -eq 255 ]; then
24677                 error "Ladvise test${i} failed, ${rc}"
24678         fi
24679 }
24680 run_test 255c "suite of ladvise lockahead tests"
24681
24682 test_256() {
24683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24684         remote_mds_nodsh && skip "remote MDS with nodsh"
24685         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24686         changelog_users $SINGLEMDS | grep "^cl" &&
24687                 skip "active changelog user"
24688
24689         local cl_user
24690         local cat_sl
24691         local mdt_dev
24692
24693         mdt_dev=$(facet_device $SINGLEMDS)
24694         echo $mdt_dev
24695
24696         changelog_register || error "changelog_register failed"
24697
24698         rm -rf $DIR/$tdir
24699         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24700
24701         changelog_clear 0 || error "changelog_clear failed"
24702
24703         # change something
24704         touch $DIR/$tdir/{1..10}
24705
24706         # stop the MDT
24707         stop $SINGLEMDS || error "Fail to stop MDT"
24708
24709         # remount the MDT
24710         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24711                 error "Fail to start MDT"
24712
24713         #after mount new plainllog is used
24714         touch $DIR/$tdir/{11..19}
24715         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24716         stack_trap "rm -f $tmpfile"
24717         cat_sl=$(do_facet $SINGLEMDS "sync; \
24718                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24719                  llog_reader $tmpfile | grep -c type=1064553b")
24720         do_facet $SINGLEMDS llog_reader $tmpfile
24721
24722         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24723
24724         changelog_clear 0 || error "changelog_clear failed"
24725
24726         cat_sl=$(do_facet $SINGLEMDS "sync; \
24727                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24728                  llog_reader $tmpfile | grep -c type=1064553b")
24729
24730         if (( cat_sl == 2 )); then
24731                 error "Empty plain llog was not deleted from changelog catalog"
24732         elif (( cat_sl != 1 )); then
24733                 error "Active plain llog shouldn't be deleted from catalog"
24734         fi
24735 }
24736 run_test 256 "Check llog delete for empty and not full state"
24737
24738 test_257() {
24739         remote_mds_nodsh && skip "remote MDS with nodsh"
24740         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24741                 skip "Need MDS version at least 2.8.55"
24742
24743         test_mkdir $DIR/$tdir
24744
24745         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24746                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24747         stat $DIR/$tdir
24748
24749 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24750         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24751         local facet=mds$((mdtidx + 1))
24752         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24753         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24754
24755         stop $facet || error "stop MDS failed"
24756         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24757                 error "start MDS fail"
24758         wait_recovery_complete $facet
24759 }
24760 run_test 257 "xattr locks are not lost"
24761
24762 # Verify we take the i_mutex when security requires it
24763 test_258a() {
24764 #define OBD_FAIL_IMUTEX_SEC 0x141c
24765         $LCTL set_param fail_loc=0x141c
24766         touch $DIR/$tfile
24767         chmod u+s $DIR/$tfile
24768         chmod a+rwx $DIR/$tfile
24769         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24770         RC=$?
24771         if [ $RC -ne 0 ]; then
24772                 error "error, failed to take i_mutex, rc=$?"
24773         fi
24774         rm -f $DIR/$tfile
24775 }
24776 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24777
24778 # Verify we do NOT take the i_mutex in the normal case
24779 test_258b() {
24780 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24781         $LCTL set_param fail_loc=0x141d
24782         touch $DIR/$tfile
24783         chmod a+rwx $DIR
24784         chmod a+rw $DIR/$tfile
24785         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24786         RC=$?
24787         if [ $RC -ne 0 ]; then
24788                 error "error, took i_mutex unnecessarily, rc=$?"
24789         fi
24790         rm -f $DIR/$tfile
24791
24792 }
24793 run_test 258b "verify i_mutex security behavior"
24794
24795 test_259() {
24796         local file=$DIR/$tfile
24797         local before
24798         local after
24799
24800         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24801
24802         stack_trap "rm -f $file" EXIT
24803
24804         wait_delete_completed
24805         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24806         echo "before: $before"
24807
24808         $LFS setstripe -i 0 -c 1 $file
24809         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24810         sync_all_data
24811         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24812         echo "after write: $after"
24813
24814 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24815         do_facet ost1 $LCTL set_param fail_loc=0x2301
24816         $TRUNCATE $file 0
24817         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24818         echo "after truncate: $after"
24819
24820         stop ost1
24821         do_facet ost1 $LCTL set_param fail_loc=0
24822         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24823         sleep 2
24824         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24825         echo "after restart: $after"
24826         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24827                 error "missing truncate?"
24828
24829         return 0
24830 }
24831 run_test 259 "crash at delayed truncate"
24832
24833 test_260() {
24834 #define OBD_FAIL_MDC_CLOSE               0x806
24835         $LCTL set_param fail_loc=0x80000806
24836         touch $DIR/$tfile
24837
24838 }
24839 run_test 260 "Check mdc_close fail"
24840
24841 ### Data-on-MDT sanity tests ###
24842 test_270a() {
24843         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24844                 skip "Need MDS version at least 2.10.55 for DoM"
24845
24846         # create DoM file
24847         local dom=$DIR/$tdir/dom_file
24848         local tmp=$DIR/$tdir/tmp_file
24849
24850         mkdir_on_mdt0 $DIR/$tdir
24851
24852         # basic checks for DoM component creation
24853         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24854                 error "Can set MDT layout to non-first entry"
24855
24856         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24857                 error "Can define multiple entries as MDT layout"
24858
24859         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24860
24861         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24862         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24863         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24864
24865         local mdtidx=$($LFS getstripe -m $dom)
24866         local mdtname=MDT$(printf %04x $mdtidx)
24867         local facet=mds$((mdtidx + 1))
24868         local space_check=1
24869
24870         # Skip free space checks with ZFS
24871         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24872
24873         # write
24874         sync
24875         local size_tmp=$((65536 * 3))
24876         local mdtfree1=$(do_facet $facet \
24877                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24878
24879         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24880         # check also direct IO along write
24881         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24882         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24883         sync
24884         cmp $tmp $dom || error "file data is different"
24885         [ $(stat -c%s $dom) == $size_tmp ] ||
24886                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24887         if [ $space_check == 1 ]; then
24888                 local mdtfree2=$(do_facet $facet \
24889                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24890
24891                 # increase in usage from by $size_tmp
24892                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24893                         error "MDT free space wrong after write: " \
24894                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24895         fi
24896
24897         # truncate
24898         local size_dom=10000
24899
24900         $TRUNCATE $dom $size_dom
24901         [ $(stat -c%s $dom) == $size_dom ] ||
24902                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24903         if [ $space_check == 1 ]; then
24904                 mdtfree1=$(do_facet $facet \
24905                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24906                 # decrease in usage from $size_tmp to new $size_dom
24907                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24908                   $(((size_tmp - size_dom) / 1024)) ] ||
24909                         error "MDT free space is wrong after truncate: " \
24910                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24911         fi
24912
24913         # append
24914         cat $tmp >> $dom
24915         sync
24916         size_dom=$((size_dom + size_tmp))
24917         [ $(stat -c%s $dom) == $size_dom ] ||
24918                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24919         if [ $space_check == 1 ]; then
24920                 mdtfree2=$(do_facet $facet \
24921                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24922                 # increase in usage by $size_tmp from previous
24923                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24924                         error "MDT free space is wrong after append: " \
24925                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24926         fi
24927
24928         # delete
24929         rm $dom
24930         if [ $space_check == 1 ]; then
24931                 mdtfree1=$(do_facet $facet \
24932                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24933                 # decrease in usage by $size_dom from previous
24934                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24935                         error "MDT free space is wrong after removal: " \
24936                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24937         fi
24938
24939         # combined striping
24940         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24941                 error "Can't create DoM + OST striping"
24942
24943         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24944         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24945         # check also direct IO along write
24946         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24947         sync
24948         cmp $tmp $dom || error "file data is different"
24949         [ $(stat -c%s $dom) == $size_tmp ] ||
24950                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24951         rm $dom $tmp
24952
24953         return 0
24954 }
24955 run_test 270a "DoM: basic functionality tests"
24956
24957 test_270b() {
24958         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24959                 skip "Need MDS version at least 2.10.55"
24960
24961         local dom=$DIR/$tdir/dom_file
24962         local max_size=1048576
24963
24964         mkdir -p $DIR/$tdir
24965         $LFS setstripe -E $max_size -L mdt $dom
24966
24967         # truncate over the limit
24968         $TRUNCATE $dom $(($max_size + 1)) &&
24969                 error "successful truncate over the maximum size"
24970         # write over the limit
24971         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24972                 error "successful write over the maximum size"
24973         # append over the limit
24974         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24975         echo "12345" >> $dom && error "successful append over the maximum size"
24976         rm $dom
24977
24978         return 0
24979 }
24980 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24981
24982 test_270c() {
24983         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24984                 skip "Need MDS version at least 2.10.55"
24985
24986         mkdir -p $DIR/$tdir
24987         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24988
24989         # check files inherit DoM EA
24990         touch $DIR/$tdir/first
24991         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24992                 error "bad pattern"
24993         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24994                 error "bad stripe count"
24995         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24996                 error "bad stripe size"
24997
24998         # check directory inherits DoM EA and uses it as default
24999         mkdir $DIR/$tdir/subdir
25000         touch $DIR/$tdir/subdir/second
25001         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
25002                 error "bad pattern in sub-directory"
25003         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
25004                 error "bad stripe count in sub-directory"
25005         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
25006                 error "bad stripe size in sub-directory"
25007         return 0
25008 }
25009 run_test 270c "DoM: DoM EA inheritance tests"
25010
25011 test_270d() {
25012         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25013                 skip "Need MDS version at least 2.10.55"
25014
25015         mkdir -p $DIR/$tdir
25016         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25017
25018         # inherit default DoM striping
25019         mkdir $DIR/$tdir/subdir
25020         touch $DIR/$tdir/subdir/f1
25021
25022         # change default directory striping
25023         $LFS setstripe -c 1 $DIR/$tdir/subdir
25024         touch $DIR/$tdir/subdir/f2
25025         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
25026                 error "wrong default striping in file 2"
25027         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
25028                 error "bad pattern in file 2"
25029         return 0
25030 }
25031 run_test 270d "DoM: change striping from DoM to RAID0"
25032
25033 test_270e() {
25034         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25035                 skip "Need MDS version at least 2.10.55"
25036
25037         mkdir -p $DIR/$tdir/dom
25038         mkdir -p $DIR/$tdir/norm
25039         DOMFILES=20
25040         NORMFILES=10
25041         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
25042         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
25043
25044         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
25045         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
25046
25047         # find DoM files by layout
25048         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
25049         [ $NUM -eq  $DOMFILES ] ||
25050                 error "lfs find -L: found $NUM, expected $DOMFILES"
25051         echo "Test 1: lfs find 20 DOM files by layout: OK"
25052
25053         # there should be 1 dir with default DOM striping
25054         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
25055         [ $NUM -eq  1 ] ||
25056                 error "lfs find -L: found $NUM, expected 1 dir"
25057         echo "Test 2: lfs find 1 DOM dir by layout: OK"
25058
25059         # find DoM files by stripe size
25060         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
25061         [ $NUM -eq  $DOMFILES ] ||
25062                 error "lfs find -S: found $NUM, expected $DOMFILES"
25063         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
25064
25065         # find files by stripe offset except DoM files
25066         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
25067         [ $NUM -eq  $NORMFILES ] ||
25068                 error "lfs find -i: found $NUM, expected $NORMFILES"
25069         echo "Test 5: lfs find no DOM files by stripe index: OK"
25070         return 0
25071 }
25072 run_test 270e "DoM: lfs find with DoM files test"
25073
25074 test_270f() {
25075         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25076                 skip "Need MDS version at least 2.10.55"
25077
25078         local mdtname=${FSNAME}-MDT0000-mdtlov
25079         local dom=$DIR/$tdir/dom_file
25080         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
25081                                                 lod.$mdtname.dom_stripesize)
25082         local dom_limit=131072
25083
25084         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
25085         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25086                                                 lod.$mdtname.dom_stripesize)
25087         [ ${dom_limit} -eq ${dom_current} ] ||
25088                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
25089
25090         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25091         $LFS setstripe -d $DIR/$tdir
25092         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
25093                 error "Can't set directory default striping"
25094
25095         # exceed maximum stripe size
25096         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25097                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
25098         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
25099                 error "Able to create DoM component size more than LOD limit"
25100
25101         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25102         dom_current=$(do_facet mds1 $LCTL get_param -n \
25103                                                 lod.$mdtname.dom_stripesize)
25104         [ 0 -eq ${dom_current} ] ||
25105                 error "Can't set zero DoM stripe limit"
25106         rm $dom
25107
25108         # attempt to create DoM file on server with disabled DoM should
25109         # remove DoM entry from layout and be succeed
25110         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
25111                 error "Can't create DoM file (DoM is disabled)"
25112         [ $($LFS getstripe -L $dom) == "mdt" ] &&
25113                 error "File has DoM component while DoM is disabled"
25114         rm $dom
25115
25116         # attempt to create DoM file with only DoM stripe should return error
25117         $LFS setstripe -E $dom_limit -L mdt $dom &&
25118                 error "Able to create DoM-only file while DoM is disabled"
25119
25120         # too low values to be aligned with smallest stripe size 64K
25121         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
25122         dom_current=$(do_facet mds1 $LCTL get_param -n \
25123                                                 lod.$mdtname.dom_stripesize)
25124         [ 30000 -eq ${dom_current} ] &&
25125                 error "Can set too small DoM stripe limit"
25126
25127         # 64K is a minimal stripe size in Lustre, expect limit of that size
25128         [ 65536 -eq ${dom_current} ] ||
25129                 error "Limit is not set to 64K but ${dom_current}"
25130
25131         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
25132         dom_current=$(do_facet mds1 $LCTL get_param -n \
25133                                                 lod.$mdtname.dom_stripesize)
25134         echo $dom_current
25135         [ 2147483648 -eq ${dom_current} ] &&
25136                 error "Can set too large DoM stripe limit"
25137
25138         do_facet mds1 $LCTL set_param -n \
25139                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
25140         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25141                 error "Can't create DoM component size after limit change"
25142         do_facet mds1 $LCTL set_param -n \
25143                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
25144         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25145                 error "Can't create DoM file after limit decrease"
25146         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25147                 error "Can create big DoM component after limit decrease"
25148         touch ${dom}_def ||
25149                 error "Can't create file with old default layout"
25150
25151         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25152         return 0
25153 }
25154 run_test 270f "DoM: maximum DoM stripe size checks"
25155
25156 test_270g() {
25157         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25158                 skip "Need MDS version at least 2.13.52"
25159         local dom=$DIR/$tdir/$tfile
25160
25161         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25162         local lodname=${FSNAME}-MDT0000-mdtlov
25163
25164         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25165         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25166         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25167         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25168
25169         local dom_limit=1024
25170         local dom_threshold="50%"
25171
25172         $LFS setstripe -d $DIR/$tdir
25173         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25174                 error "Can't set directory default striping"
25175
25176         do_facet mds1 $LCTL set_param -n \
25177                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25178         # set 0 threshold and create DOM file to change tunable stripesize
25179         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25180         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25181                 error "Failed to create $dom file"
25182         # now tunable dom_cur_stripesize should reach maximum
25183         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25184                                         lod.${lodname}.dom_stripesize_cur_kb)
25185         [[ $dom_current == $dom_limit ]] ||
25186                 error "Current DOM stripesize is not maximum"
25187         rm $dom
25188
25189         # set threshold for further tests
25190         do_facet mds1 $LCTL set_param -n \
25191                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25192         echo "DOM threshold is $dom_threshold free space"
25193         local dom_def
25194         local dom_set
25195         # Spoof bfree to exceed threshold
25196         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25197         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25198         for spfree in 40 20 0 15 30 55; do
25199                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25200                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25201                         error "Failed to create $dom file"
25202                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25203                                         lod.${lodname}.dom_stripesize_cur_kb)
25204                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25205                 [[ $dom_def != $dom_current ]] ||
25206                         error "Default stripe size was not changed"
25207                 if (( spfree > 0 )) ; then
25208                         dom_set=$($LFS getstripe -S $dom)
25209                         (( dom_set == dom_def * 1024 )) ||
25210                                 error "DOM component size is still old"
25211                 else
25212                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25213                                 error "DoM component is set with no free space"
25214                 fi
25215                 rm $dom
25216                 dom_current=$dom_def
25217         done
25218 }
25219 run_test 270g "DoM: default DoM stripe size depends on free space"
25220
25221 test_270h() {
25222         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25223                 skip "Need MDS version at least 2.13.53"
25224
25225         local mdtname=${FSNAME}-MDT0000-mdtlov
25226         local dom=$DIR/$tdir/$tfile
25227         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25228
25229         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25230         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25231
25232         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25233         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25234                 error "can't create OST file"
25235         # mirrored file with DOM entry in the second mirror
25236         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25237                 error "can't create mirror with DoM component"
25238
25239         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25240
25241         # DOM component in the middle and has other enries in the same mirror,
25242         # should succeed but lost DoM component
25243         $LFS setstripe --copy=${dom}_1 $dom ||
25244                 error "Can't create file from OST|DOM mirror layout"
25245         # check new file has no DoM layout after all
25246         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25247                 error "File has DoM component while DoM is disabled"
25248 }
25249 run_test 270h "DoM: DoM stripe removal when disabled on server"
25250
25251 test_270i() {
25252         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25253                 skip "Need MDS version at least 2.14.54"
25254
25255         mkdir $DIR/$tdir
25256         # DoM with plain layout
25257         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25258                 error "default plain layout with DoM must fail"
25259         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25260                 error "setstripe plain file layout with DoM must fail"
25261         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25262                 error "default DoM layout with bad striping must fail"
25263         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25264                 error "setstripe to DoM layout with bad striping must fail"
25265         return 0
25266 }
25267 run_test 270i "DoM: setting invalid DoM striping should fail"
25268
25269 test_270j() {
25270         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25271                 skip "Need MDS version at least 2.15.55.203"
25272
25273         local dom=$DIR/$tdir/$tfile
25274         local odv
25275         local ndv
25276
25277         mkdir -p $DIR/$tdir
25278
25279         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25280
25281         odv=$($LFS data_version $dom)
25282         chmod 666 $dom
25283         mv $dom ${dom}_moved
25284         link ${dom}_moved $dom
25285         setfattr -n user.attrx -v "some_attr" $dom
25286         ndv=$($LFS data_version $dom)
25287         (( $ndv == $odv )) ||
25288                 error "data version was changed by metadata operations"
25289
25290         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25291                 error "failed to write data into $dom"
25292         cancel_lru_locks mdc
25293         ndv=$($LFS data_version $dom)
25294         (( $ndv != $odv )) ||
25295                 error "data version wasn't changed on write"
25296
25297         odv=$ndv
25298         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25299         ndv=$($LFS data_version $dom)
25300         (( $ndv != $odv )) ||
25301                 error "data version wasn't changed on truncate down"
25302
25303         odv=$ndv
25304         $TRUNCATE $dom 25000
25305         ndv=$($LFS data_version $dom)
25306         (( $ndv != $odv )) ||
25307                 error "data version wasn't changed on truncate up"
25308
25309         # check also fallocate for ldiskfs
25310         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25311                 odv=$ndv
25312                 fallocate -l 1048576 $dom
25313                 ndv=$($LFS data_version $dom)
25314                 (( $ndv != $odv )) ||
25315                         error "data version wasn't changed on fallocate"
25316
25317                 odv=$ndv
25318                 fallocate -p --offset 4096 -l 4096 $dom
25319                 ndv=$($LFS data_version $dom)
25320                 (( $ndv != $odv )) ||
25321                         error "data version wasn't changed on fallocate punch"
25322         fi
25323 }
25324 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25325
25326 test_271a() {
25327         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25328                 skip "Need MDS version at least 2.10.55"
25329
25330         local dom=$DIR/$tdir/dom
25331
25332         mkdir -p $DIR/$tdir
25333
25334         $LFS setstripe -E 1024K -L mdt $dom
25335
25336         lctl set_param -n mdc.*.stats=clear
25337         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25338         cat $dom > /dev/null
25339         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25340         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25341         ls $dom
25342         rm -f $dom
25343 }
25344 run_test 271a "DoM: data is cached for read after write"
25345
25346 test_271b() {
25347         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25348                 skip "Need MDS version at least 2.10.55"
25349
25350         local dom=$DIR/$tdir/dom
25351
25352         mkdir -p $DIR/$tdir
25353
25354         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25355
25356         lctl set_param -n mdc.*.stats=clear
25357         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25358         cancel_lru_locks mdc
25359         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25360         # second stat to check size is cached on client
25361         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25362         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25363         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25364         rm -f $dom
25365 }
25366 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25367
25368 test_271ba() {
25369         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25370                 skip "Need MDS version at least 2.10.55"
25371
25372         local dom=$DIR/$tdir/dom
25373
25374         mkdir -p $DIR/$tdir
25375
25376         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25377
25378         lctl set_param -n mdc.*.stats=clear
25379         lctl set_param -n osc.*.stats=clear
25380         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25381         cancel_lru_locks mdc
25382         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25383         # second stat to check size is cached on client
25384         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25385         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25386         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25387         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25388         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25389         rm -f $dom
25390 }
25391 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25392
25393
25394 get_mdc_stats() {
25395         local mdtidx=$1
25396         local param=$2
25397         local mdt=MDT$(printf %04x $mdtidx)
25398
25399         if [ -z $param ]; then
25400                 lctl get_param -n mdc.*$mdt*.stats
25401         else
25402                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25403         fi
25404 }
25405
25406 test_271c() {
25407         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25408                 skip "Need MDS version at least 2.10.55"
25409
25410         local dom=$DIR/$tdir/dom
25411
25412         mkdir -p $DIR/$tdir
25413
25414         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25415
25416         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25417         local facet=mds$((mdtidx + 1))
25418
25419         cancel_lru_locks mdc
25420         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25421         createmany -o $dom 1000
25422         lctl set_param -n mdc.*.stats=clear
25423         smalliomany -w $dom 1000 200
25424         get_mdc_stats $mdtidx
25425         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25426         # Each file has 1 open, 1 IO enqueues, total 2000
25427         # but now we have also +1 getxattr for security.capability, total 3000
25428         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25429         unlinkmany $dom 1000
25430
25431         cancel_lru_locks mdc
25432         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25433         createmany -o $dom 1000
25434         lctl set_param -n mdc.*.stats=clear
25435         smalliomany -w $dom 1000 200
25436         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25437         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25438         # for OPEN and IO lock.
25439         [ $((enq - enq_2)) -ge 1000 ] ||
25440                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25441         unlinkmany $dom 1000
25442         return 0
25443 }
25444 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25445
25446 cleanup_271def_tests() {
25447         trap 0
25448         rm -f $1
25449 }
25450
25451 test_271d() {
25452         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25453                 skip "Need MDS version at least 2.10.57"
25454
25455         local dom=$DIR/$tdir/dom
25456         local tmp=$TMP/$tfile
25457         trap "cleanup_271def_tests $tmp" EXIT
25458
25459         mkdir -p $DIR/$tdir
25460
25461         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25462
25463         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25464
25465         cancel_lru_locks mdc
25466         dd if=/dev/urandom of=$tmp bs=1000 count=1
25467         dd if=$tmp of=$dom bs=1000 count=1
25468         cancel_lru_locks mdc
25469
25470         cat /etc/hosts >> $tmp
25471         lctl set_param -n mdc.*.stats=clear
25472
25473         # append data to the same file it should update local page
25474         echo "Append to the same page"
25475         cat /etc/hosts >> $dom
25476         local num=$(get_mdc_stats $mdtidx ost_read)
25477         local ra=$(get_mdc_stats $mdtidx req_active)
25478         local rw=$(get_mdc_stats $mdtidx req_waittime)
25479
25480         [ -z $num ] || error "$num READ RPC occured"
25481         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25482         echo "... DONE"
25483
25484         # compare content
25485         cmp $tmp $dom || error "file miscompare"
25486
25487         cancel_lru_locks mdc
25488         lctl set_param -n mdc.*.stats=clear
25489
25490         echo "Open and read file"
25491         cat $dom > /dev/null
25492         local num=$(get_mdc_stats $mdtidx ost_read)
25493         local ra=$(get_mdc_stats $mdtidx req_active)
25494         local rw=$(get_mdc_stats $mdtidx req_waittime)
25495
25496         [ -z $num ] || error "$num READ RPC occured"
25497         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25498         echo "... DONE"
25499
25500         # compare content
25501         cmp $tmp $dom || error "file miscompare"
25502
25503         return 0
25504 }
25505 run_test 271d "DoM: read on open (1K file in reply buffer)"
25506
25507 test_271f() {
25508         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25509                 skip "Need MDS version at least 2.10.57"
25510
25511         local dom=$DIR/$tdir/dom
25512         local tmp=$TMP/$tfile
25513         trap "cleanup_271def_tests $tmp" EXIT
25514
25515         mkdir -p $DIR/$tdir
25516
25517         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25518
25519         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25520
25521         cancel_lru_locks mdc
25522         dd if=/dev/urandom of=$tmp bs=265000 count=1
25523         dd if=$tmp of=$dom bs=265000 count=1
25524         cancel_lru_locks mdc
25525         cat /etc/hosts >> $tmp
25526         lctl set_param -n mdc.*.stats=clear
25527
25528         echo "Append to the same page"
25529         cat /etc/hosts >> $dom
25530         local num=$(get_mdc_stats $mdtidx ost_read)
25531         local ra=$(get_mdc_stats $mdtidx req_active)
25532         local rw=$(get_mdc_stats $mdtidx req_waittime)
25533
25534         [ -z $num ] || error "$num READ RPC occured"
25535         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25536         echo "... DONE"
25537
25538         # compare content
25539         cmp $tmp $dom || error "file miscompare"
25540
25541         cancel_lru_locks mdc
25542         lctl set_param -n mdc.*.stats=clear
25543
25544         echo "Open and read file"
25545         cat $dom > /dev/null
25546         local num=$(get_mdc_stats $mdtidx ost_read)
25547         local ra=$(get_mdc_stats $mdtidx req_active)
25548         local rw=$(get_mdc_stats $mdtidx req_waittime)
25549
25550         [ -z $num ] && num=0
25551         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25552         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25553         echo "... DONE"
25554
25555         # compare content
25556         cmp $tmp $dom || error "file miscompare"
25557
25558         return 0
25559 }
25560 run_test 271f "DoM: read on open (200K file and read tail)"
25561
25562 test_271g() {
25563         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25564                 skip "Skipping due to old client or server version"
25565
25566         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25567         # to get layout
25568         $CHECKSTAT -t file $DIR1/$tfile
25569
25570         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25571         MULTIOP_PID=$!
25572         sleep 1
25573         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25574         $LCTL set_param fail_loc=0x80000314
25575         rm $DIR1/$tfile || error "Unlink fails"
25576         RC=$?
25577         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25578         [ $RC -eq 0 ] || error "Failed write to stale object"
25579 }
25580 run_test 271g "Discard DoM data vs client flush race"
25581
25582 test_272a() {
25583         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25584                 skip "Need MDS version at least 2.11.50"
25585
25586         local dom=$DIR/$tdir/dom
25587         mkdir -p $DIR/$tdir
25588
25589         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25590         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25591                 error "failed to write data into $dom"
25592         local old_md5=$(md5sum $dom)
25593
25594         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25595                 error "failed to migrate to the same DoM component"
25596
25597         local new_md5=$(md5sum $dom)
25598
25599         [ "$old_md5" == "$new_md5" ] ||
25600                 error "md5sum differ: $old_md5, $new_md5"
25601
25602         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25603                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25604 }
25605 run_test 272a "DoM migration: new layout with the same DOM component"
25606
25607 test_272b() {
25608         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25609                 skip "Need MDS version at least 2.11.50"
25610
25611         local dom=$DIR/$tdir/dom
25612         mkdir -p $DIR/$tdir
25613         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25614         stack_trap "rm -rf $DIR/$tdir"
25615
25616         local mdtidx=$($LFS getstripe -m $dom)
25617         local mdtname=MDT$(printf %04x $mdtidx)
25618         local facet=mds$((mdtidx + 1))
25619
25620         local mdtfree1=$(do_facet $facet \
25621                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25622         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25623                 error "failed to write data into $dom"
25624         local old_md5=$(md5sum $dom)
25625         cancel_lru_locks mdc
25626         local mdtfree1=$(do_facet $facet \
25627                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25628
25629         $LFS migrate -c2 $dom ||
25630                 error "failed to migrate to the new composite layout"
25631         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25632                 error "MDT stripe was not removed"
25633         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25634                 error "$dir1 shouldn't have DATAVER EA"
25635
25636         cancel_lru_locks mdc
25637         local new_md5=$(md5sum $dom)
25638         [ "$old_md5" == "$new_md5" ] ||
25639                 error "$old_md5 != $new_md5"
25640
25641         # Skip free space checks with ZFS
25642         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25643                 local mdtfree2=$(do_facet $facet \
25644                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25645                 [ $mdtfree2 -gt $mdtfree1 ] ||
25646                         error "MDT space is not freed after migration"
25647         fi
25648         return 0
25649 }
25650 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25651
25652 test_272c() {
25653         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25654                 skip "Need MDS version at least 2.11.50"
25655
25656         local dom=$DIR/$tdir/$tfile
25657         mkdir -p $DIR/$tdir
25658         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25659         stack_trap "rm -rf $DIR/$tdir"
25660
25661         local mdtidx=$($LFS getstripe -m $dom)
25662         local mdtname=MDT$(printf %04x $mdtidx)
25663         local facet=mds$((mdtidx + 1))
25664
25665         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25666                 error "failed to write data into $dom"
25667         local old_md5=$(md5sum $dom)
25668         cancel_lru_locks mdc
25669         local mdtfree1=$(do_facet $facet \
25670                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25671
25672         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25673                 error "failed to migrate to the new composite layout"
25674         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25675                 error "MDT stripe was not removed"
25676
25677         cancel_lru_locks mdc
25678         local new_md5=$(md5sum $dom)
25679         [ "$old_md5" == "$new_md5" ] ||
25680                 error "$old_md5 != $new_md5"
25681
25682         # Skip free space checks with ZFS
25683         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25684                 local mdtfree2=$(do_facet $facet \
25685                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25686                 [ $mdtfree2 -gt $mdtfree1 ] ||
25687                         error "MDS space is not freed after migration"
25688         fi
25689         return 0
25690 }
25691 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25692
25693 test_272d() {
25694         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25695                 skip "Need MDS version at least 2.12.55"
25696
25697         local dom=$DIR/$tdir/$tfile
25698         mkdir -p $DIR/$tdir
25699         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25700
25701         local mdtidx=$($LFS getstripe -m $dom)
25702         local mdtname=MDT$(printf %04x $mdtidx)
25703         local facet=mds$((mdtidx + 1))
25704
25705         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25706                 error "failed to write data into $dom"
25707         local old_md5=$(md5sum $dom)
25708         cancel_lru_locks mdc
25709         local mdtfree1=$(do_facet $facet \
25710                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25711
25712         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25713                 error "failed mirroring to the new composite layout"
25714         $LFS mirror resync $dom ||
25715                 error "failed mirror resync"
25716         $LFS mirror split --mirror-id 1 -d $dom ||
25717                 error "failed mirror split"
25718
25719         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25720                 error "MDT stripe was not removed"
25721
25722         cancel_lru_locks mdc
25723         local new_md5=$(md5sum $dom)
25724         [ "$old_md5" == "$new_md5" ] ||
25725                 error "$old_md5 != $new_md5"
25726
25727         # Skip free space checks with ZFS
25728         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25729                 local mdtfree2=$(do_facet $facet \
25730                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25731                 [ $mdtfree2 -gt $mdtfree1 ] ||
25732                         error "MDS space is not freed after DOM mirror deletion"
25733         fi
25734         return 0
25735 }
25736 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25737
25738 test_272e() {
25739         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25740                 skip "Need MDS version at least 2.12.55"
25741
25742         local dom=$DIR/$tdir/$tfile
25743         mkdir -p $DIR/$tdir
25744         $LFS setstripe -c 2 $dom
25745
25746         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25747                 error "failed to write data into $dom"
25748         local old_md5=$(md5sum $dom)
25749         cancel_lru_locks
25750
25751         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25752                 error "failed mirroring to the DOM layout"
25753         $LFS mirror resync $dom ||
25754                 error "failed mirror resync"
25755         $LFS mirror split --mirror-id 1 -d $dom ||
25756                 error "failed mirror split"
25757
25758         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25759                 error "MDT stripe wasn't set"
25760
25761         cancel_lru_locks
25762         local new_md5=$(md5sum $dom)
25763         [ "$old_md5" == "$new_md5" ] ||
25764                 error "$old_md5 != $new_md5"
25765
25766         return 0
25767 }
25768 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25769
25770 test_272f() {
25771         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25772                 skip "Need MDS version at least 2.12.55"
25773
25774         local dom=$DIR/$tdir/$tfile
25775         mkdir -p $DIR/$tdir
25776         $LFS setstripe -c 2 $dom
25777
25778         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25779                 error "failed to write data into $dom"
25780         local old_md5=$(md5sum $dom)
25781         cancel_lru_locks
25782
25783         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25784                 error "failed migrating to the DOM file"
25785
25786         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25787                 error "MDT stripe wasn't set"
25788
25789         cancel_lru_locks
25790         local new_md5=$(md5sum $dom)
25791         [ "$old_md5" != "$new_md5" ] &&
25792                 error "$old_md5 != $new_md5"
25793
25794         return 0
25795 }
25796 run_test 272f "DoM migration: OST-striped file to DOM file"
25797
25798 test_273a() {
25799         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25800                 skip "Need MDS version at least 2.11.50"
25801
25802         # Layout swap cannot be done if either file has DOM component,
25803         # this will never be supported, migration should be used instead
25804
25805         local dom=$DIR/$tdir/$tfile
25806         mkdir -p $DIR/$tdir
25807
25808         $LFS setstripe -c2 ${dom}_plain
25809         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25810         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25811                 error "can swap layout with DoM component"
25812         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25813                 error "can swap layout with DoM component"
25814
25815         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25816         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25817                 error "can swap layout with DoM component"
25818         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25819                 error "can swap layout with DoM component"
25820         return 0
25821 }
25822 run_test 273a "DoM: layout swapping should fail with DOM"
25823
25824 test_273b() {
25825         mkdir -p $DIR/$tdir
25826         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25827
25828 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25829         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25830
25831         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25832 }
25833 run_test 273b "DoM: race writeback and object destroy"
25834
25835 test_273c() {
25836         mkdir -p $DIR/$tdir
25837         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25838
25839         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25840         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25841
25842         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25843 }
25844 run_test 273c "race writeback and object destroy"
25845
25846 test_275() {
25847         remote_ost_nodsh && skip "remote OST with nodsh"
25848         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25849                 skip "Need OST version >= 2.10.57"
25850
25851         local file=$DIR/$tfile
25852         local oss
25853
25854         oss=$(comma_list $(osts_nodes))
25855
25856         dd if=/dev/urandom of=$file bs=1M count=2 ||
25857                 error "failed to create a file"
25858         stack_trap "rm -f $file"
25859         cancel_lru_locks osc
25860
25861         #lock 1
25862         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25863                 error "failed to read a file"
25864
25865 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25866         $LCTL set_param fail_loc=0x8000031f
25867
25868         cancel_lru_locks osc &
25869         sleep 1
25870
25871 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25872         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25873         #IO takes another lock, but matches the PENDING one
25874         #and places it to the IO RPC
25875         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25876                 error "failed to read a file with PENDING lock"
25877 }
25878 run_test 275 "Read on a canceled duplicate lock"
25879
25880 test_276() {
25881         remote_ost_nodsh && skip "remote OST with nodsh"
25882         local pid
25883
25884         do_facet ost1 "(while true; do \
25885                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25886                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25887         pid=$!
25888
25889         for LOOP in $(seq 20); do
25890                 stop ost1
25891                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25892         done
25893         kill -9 $pid
25894         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25895                 rm $TMP/sanity_276_pid"
25896 }
25897 run_test 276 "Race between mount and obd_statfs"
25898
25899 test_277() {
25900         $LCTL set_param ldlm.namespaces.*.lru_size=0
25901         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25902         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25903                           awk '/^used_mb/ { print $2 }')
25904         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25905         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25906                 oflag=direct conv=notrunc
25907         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25908                     awk '/^used_mb/ { print $2 }')
25909         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25910 }
25911 run_test 277 "Direct IO shall drop page cache"
25912
25913 test_278() {
25914         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25915         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25916         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25917                 skip "needs the same host for mdt1 mdt2" && return
25918
25919         local pid1
25920         local pid2
25921
25922 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25923         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25924         stop mds2 &
25925         pid2=$!
25926
25927         stop mds1
25928
25929         echo "Starting MDTs"
25930         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25931         wait $pid2
25932 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25933 #will return NULL
25934         do_facet mds2 $LCTL set_param fail_loc=0
25935
25936         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25937         wait_recovery_complete mds2
25938 }
25939 run_test 278 "Race starting MDS between MDTs stop/start"
25940
25941 test_280() {
25942         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25943                 skip "Need MGS version at least 2.13.52"
25944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25945         combined_mgs_mds || skip "needs combined MGS/MDT"
25946
25947         umount_client $MOUNT
25948 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25949         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25950
25951         mount_client $MOUNT &
25952         sleep 1
25953         stop mgs || error "stop mgs failed"
25954         #for a race mgs would crash
25955         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25956         # make sure we unmount client before remounting
25957         wait
25958         umount_client $MOUNT
25959         mount_client $MOUNT || error "mount client failed"
25960 }
25961 run_test 280 "Race between MGS umount and client llog processing"
25962
25963 cleanup_test_300() {
25964         trap 0
25965         umask $SAVE_UMASK
25966 }
25967
25968 test_striped_dir() {
25969         local mdt_index=$1
25970         local stripe_count=$2
25971         local overstriping=$3
25972         local stripe_index
25973         local getstripe_count
25974
25975         mkdir -p $DIR/$tdir
25976
25977         SAVE_UMASK=$(umask)
25978         trap cleanup_test_300 RETURN EXIT
25979
25980         if [ -z $overstriping ]; then
25981                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25982                                         -o 755 $DIR/$tdir/striped_dir ||
25983                         error "set striped dir error"
25984         else
25985                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25986                                         -o 755 $DIR/$tdir/striped_dir ||
25987                         error "set striped dir error"
25988         fi
25989
25990         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25991         [ "$mode" = "755" ] || error "expect 755 got $mode"
25992
25993         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25994                 error "getdirstripe failed"
25995         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25996         if [ "$getstripe_count" != "$stripe_count" ]; then
25997                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25998         fi
25999         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
26000         if [ "$getstripe_count" != "$stripe_count" ]; then
26001                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
26002         fi
26003
26004         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
26005         if [ "$stripe_index" != "$mdt_index" ]; then
26006                 error "stripe_index is $stripe_index, expect $mdt_index"
26007         fi
26008
26009         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
26010                 error "nlink error after create striped dir"
26011
26012         mkdir $DIR/$tdir/striped_dir/a
26013         mkdir $DIR/$tdir/striped_dir/b
26014
26015         stat $DIR/$tdir/striped_dir/a ||
26016                 error "create dir under striped dir failed"
26017         stat $DIR/$tdir/striped_dir/b ||
26018                 error "create dir under striped dir failed"
26019
26020         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
26021                 error "nlink error after mkdir"
26022
26023         rmdir $DIR/$tdir/striped_dir/a
26024         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
26025                 error "nlink error after rmdir"
26026
26027         rmdir $DIR/$tdir/striped_dir/b
26028         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
26029                 error "nlink error after rmdir"
26030
26031         chattr +i $DIR/$tdir/striped_dir
26032         createmany -o $DIR/$tdir/striped_dir/f 10 &&
26033                 error "immutable flags not working under striped dir!"
26034         chattr -i $DIR/$tdir/striped_dir
26035
26036         rmdir $DIR/$tdir/striped_dir ||
26037                 error "rmdir striped dir error"
26038
26039         cleanup_test_300
26040
26041         true
26042 }
26043
26044 test_300a() {
26045         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26046                 skip "skipped for lustre < 2.7.0"
26047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26049
26050         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
26051         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
26052 }
26053 run_test 300a "basic striped dir sanity test"
26054
26055 test_300b() {
26056         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26057                 skip "skipped for lustre < 2.7.0"
26058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26059         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26060
26061         local i
26062         local mtime1
26063         local mtime2
26064         local mtime3
26065
26066         test_mkdir $DIR/$tdir || error "mkdir fail"
26067         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26068                 error "set striped dir error"
26069         for i in {0..9}; do
26070                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
26071                 sleep 1
26072                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
26073                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
26074                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
26075                 sleep 1
26076                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
26077                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
26078                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
26079         done
26080         true
26081 }
26082 run_test 300b "check ctime/mtime for striped dir"
26083
26084 test_300c() {
26085         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26086                 skip "skipped for lustre < 2.7.0"
26087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26089
26090         local file_count
26091
26092         mkdir_on_mdt0 $DIR/$tdir
26093         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
26094                 error "set striped dir error"
26095
26096         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
26097                 error "chown striped dir failed"
26098
26099         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
26100                 error "create 5k files failed"
26101
26102         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
26103
26104         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
26105
26106         rm -rf $DIR/$tdir
26107 }
26108 run_test 300c "chown && check ls under striped directory"
26109
26110 test_300d() {
26111         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26112                 skip "skipped for lustre < 2.7.0"
26113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26114         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26115
26116         local stripe_count
26117         local file
26118
26119         mkdir -p $DIR/$tdir
26120         $LFS setstripe -c 2 $DIR/$tdir
26121
26122         #local striped directory
26123         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26124                 error "set striped dir error"
26125         #look at the directories for debug purposes
26126         ls -l $DIR/$tdir
26127         $LFS getdirstripe $DIR/$tdir
26128         ls -l $DIR/$tdir/striped_dir
26129         $LFS getdirstripe $DIR/$tdir/striped_dir
26130         createmany -o $DIR/$tdir/striped_dir/f 10 ||
26131                 error "create 10 files failed"
26132
26133         #remote striped directory
26134         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
26135                 error "set striped dir error"
26136         #look at the directories for debug purposes
26137         ls -l $DIR/$tdir
26138         $LFS getdirstripe $DIR/$tdir
26139         ls -l $DIR/$tdir/remote_striped_dir
26140         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
26141         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
26142                 error "create 10 files failed"
26143
26144         for file in $(find $DIR/$tdir); do
26145                 stripe_count=$($LFS getstripe -c $file)
26146                 [ $stripe_count -eq 2 ] ||
26147                         error "wrong stripe $stripe_count for $file"
26148         done
26149
26150         rm -rf $DIR/$tdir
26151 }
26152 run_test 300d "check default stripe under striped directory"
26153
26154 test_300e() {
26155         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26156                 skip "Need MDS version at least 2.7.55"
26157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26158         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26159
26160         local stripe_count
26161         local file
26162
26163         mkdir -p $DIR/$tdir
26164
26165         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26166                 error "set striped dir error"
26167
26168         touch $DIR/$tdir/striped_dir/a
26169         touch $DIR/$tdir/striped_dir/b
26170         touch $DIR/$tdir/striped_dir/c
26171
26172         mkdir $DIR/$tdir/striped_dir/dir_a
26173         mkdir $DIR/$tdir/striped_dir/dir_b
26174         mkdir $DIR/$tdir/striped_dir/dir_c
26175
26176         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26177                 error "set striped adir under striped dir error"
26178
26179         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26180                 error "set striped bdir under striped dir error"
26181
26182         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26183                 error "set striped cdir under striped dir error"
26184
26185         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26186                 error "rename dir under striped dir fails"
26187
26188         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26189                 error "rename dir under different stripes fails"
26190
26191         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26192                 error "rename file under striped dir should succeed"
26193
26194         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26195                 error "rename dir under striped dir should succeed"
26196
26197         rm -rf $DIR/$tdir
26198 }
26199 run_test 300e "check rename under striped directory"
26200
26201 test_300f() {
26202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26204         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26205                 skip "Need MDS version at least 2.7.55"
26206
26207         local stripe_count
26208         local file
26209
26210         rm -rf $DIR/$tdir
26211         mkdir -p $DIR/$tdir
26212
26213         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26214                 error "set striped dir error"
26215
26216         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26217                 error "set striped dir error"
26218
26219         touch $DIR/$tdir/striped_dir/a
26220         mkdir $DIR/$tdir/striped_dir/dir_a
26221         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26222                 error "create striped dir under striped dir fails"
26223
26224         touch $DIR/$tdir/striped_dir1/b
26225         mkdir $DIR/$tdir/striped_dir1/dir_b
26226         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26227                 error "create striped dir under striped dir fails"
26228
26229         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26230                 error "rename dir under different striped dir should fail"
26231
26232         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26233                 error "rename striped dir under diff striped dir should fail"
26234
26235         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26236                 error "rename file under diff striped dirs fails"
26237
26238         rm -rf $DIR/$tdir
26239 }
26240 run_test 300f "check rename cross striped directory"
26241
26242 test_300_check_default_striped_dir()
26243 {
26244         local dirname=$1
26245         local default_count=$2
26246         local default_index=$3
26247         local stripe_count
26248         local stripe_index
26249         local dir_stripe_index
26250         local dir
26251
26252         echo "checking $dirname $default_count $default_index"
26253         $LFS setdirstripe -D -c $default_count -i $default_index \
26254                                 -H all_char $DIR/$tdir/$dirname ||
26255                 error "set default stripe on striped dir error"
26256         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26257         [ $stripe_count -eq $default_count ] ||
26258                 error "expect $default_count get $stripe_count for $dirname"
26259
26260         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26261         [ $stripe_index -eq $default_index ] ||
26262                 error "expect $default_index get $stripe_index for $dirname"
26263
26264         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26265                                                 error "create dirs failed"
26266
26267         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26268         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26269         for dir in $(find $DIR/$tdir/$dirname/*); do
26270                 stripe_count=$($LFS getdirstripe -c $dir)
26271                 (( $stripe_count == $default_count )) ||
26272                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26273                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26274                 error "stripe count $default_count != $stripe_count for $dir"
26275
26276                 stripe_index=$($LFS getdirstripe -i $dir)
26277                 [ $default_index -eq -1 ] ||
26278                         [ $stripe_index -eq $default_index ] ||
26279                         error "$stripe_index != $default_index for $dir"
26280
26281                 #check default stripe
26282                 stripe_count=$($LFS getdirstripe -D -c $dir)
26283                 [ $stripe_count -eq $default_count ] ||
26284                 error "default count $default_count != $stripe_count for $dir"
26285
26286                 stripe_index=$($LFS getdirstripe -D -i $dir)
26287                 [ $stripe_index -eq $default_index ] ||
26288                 error "default index $default_index != $stripe_index for $dir"
26289         done
26290         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26291 }
26292
26293 test_300g() {
26294         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26295         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26296                 skip "Need MDS version at least 2.7.55"
26297
26298         local dir
26299         local stripe_count
26300         local stripe_index
26301
26302         mkdir_on_mdt0 $DIR/$tdir
26303         mkdir $DIR/$tdir/normal_dir
26304
26305         #Checking when client cache stripe index
26306         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26307         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26308                 error "create striped_dir failed"
26309
26310         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26311                 error "create dir0 fails"
26312         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26313         [ $stripe_index -eq 0 ] ||
26314                 error "dir0 expect index 0 got $stripe_index"
26315
26316         mkdir $DIR/$tdir/striped_dir/dir1 ||
26317                 error "create dir1 fails"
26318         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26319         [ $stripe_index -eq 1 ] ||
26320                 error "dir1 expect index 1 got $stripe_index"
26321
26322         #check default stripe count/stripe index
26323         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26324         test_300_check_default_striped_dir normal_dir 1 0
26325         test_300_check_default_striped_dir normal_dir -1 1
26326         test_300_check_default_striped_dir normal_dir 2 -1
26327
26328         #delete default stripe information
26329         echo "delete default stripeEA"
26330         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26331                 error "set default stripe on striped dir error"
26332
26333         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26334         for dir in $(find $DIR/$tdir/normal_dir/*); do
26335                 stripe_count=$($LFS getdirstripe -c $dir)
26336                 [ $stripe_count -eq 0 ] ||
26337                         error "expect 1 get $stripe_count for $dir"
26338         done
26339 }
26340 run_test 300g "check default striped directory for normal directory"
26341
26342 test_300h() {
26343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26344         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26345                 skip "Need MDS version at least 2.7.55"
26346
26347         local dir
26348         local stripe_count
26349
26350         mkdir $DIR/$tdir
26351         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26352                 error "set striped dir error"
26353
26354         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26355         test_300_check_default_striped_dir striped_dir 1 0
26356         test_300_check_default_striped_dir striped_dir -1 1
26357         test_300_check_default_striped_dir striped_dir 2 -1
26358
26359         #delete default stripe information
26360         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26361                 error "set default stripe on striped dir error"
26362
26363         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26364         for dir in $(find $DIR/$tdir/striped_dir/*); do
26365                 stripe_count=$($LFS getdirstripe -c $dir)
26366                 [ $stripe_count -eq 0 ] ||
26367                         error "expect 1 get $stripe_count for $dir"
26368         done
26369 }
26370 run_test 300h "check default striped directory for striped directory"
26371
26372 test_300i() {
26373         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26374         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26375         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26376                 skip "Need MDS version at least 2.7.55"
26377
26378         local stripe_count
26379         local file
26380
26381         mkdir $DIR/$tdir
26382
26383         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26384                 error "set striped dir error"
26385
26386         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26387                 error "create files under striped dir failed"
26388
26389         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26390                 error "set striped hashdir error"
26391
26392         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26393                 error "create dir0 under hash dir failed"
26394         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26395                 error "create dir1 under hash dir failed"
26396         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26397                 error "create dir2 under hash dir failed"
26398
26399         # unfortunately, we need to umount to clear dir layout cache for now
26400         # once we fully implement dir layout, we can drop this
26401         umount_client $MOUNT || error "umount failed"
26402         mount_client $MOUNT || error "mount failed"
26403
26404         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26405         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26406         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26407
26408         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26409                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26410                         error "create crush2 dir $tdir/hashdir/d3 failed"
26411                 $LFS find -H crush2 $DIR/$tdir/hashdir
26412                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26413                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26414
26415                 # mkdir with an invalid hash type (hash=fail_val) from client
26416                 # should be replaced on MDS with a valid (default) hash type
26417                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26418                 $LCTL set_param fail_loc=0x1901 fail_val=99
26419                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26420
26421                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26422                 local expect=$(do_facet mds1 \
26423                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26424                 [[ $hash == $expect ]] ||
26425                         error "d99 hash '$hash' != expected hash '$expect'"
26426         fi
26427
26428         #set the stripe to be unknown hash type on read
26429         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26430         $LCTL set_param fail_loc=0x1901 fail_val=99
26431         for ((i = 0; i < 10; i++)); do
26432                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26433                         error "stat f-$i failed"
26434                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26435         done
26436
26437         touch $DIR/$tdir/striped_dir/f0 &&
26438                 error "create under striped dir with unknown hash should fail"
26439
26440         $LCTL set_param fail_loc=0
26441
26442         umount_client $MOUNT || error "umount failed"
26443         mount_client $MOUNT || error "mount failed"
26444
26445         return 0
26446 }
26447 run_test 300i "client handle unknown hash type striped directory"
26448
26449 test_300j() {
26450         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26452         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26453                 skip "Need MDS version at least 2.7.55"
26454
26455         local stripe_count
26456         local file
26457
26458         mkdir $DIR/$tdir
26459
26460         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26461         $LCTL set_param fail_loc=0x1702
26462         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26463                 error "set striped dir error"
26464
26465         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26466                 error "create files under striped dir failed"
26467
26468         $LCTL set_param fail_loc=0
26469
26470         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26471
26472         return 0
26473 }
26474 run_test 300j "test large update record"
26475
26476 test_300k() {
26477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26478         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26479         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26480                 skip "Need MDS version at least 2.7.55"
26481
26482         # this test needs a huge transaction
26483         local kb
26484         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26485              osd*.$FSNAME-MDT0000.kbytestotal")
26486         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26487
26488         local stripe_count
26489         local file
26490
26491         mkdir $DIR/$tdir
26492
26493         #define OBD_FAIL_LARGE_STRIPE   0x1703
26494         $LCTL set_param fail_loc=0x1703
26495         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26496                 error "set striped dir error"
26497         $LCTL set_param fail_loc=0
26498
26499         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26500                 error "getstripeddir fails"
26501         rm -rf $DIR/$tdir/striped_dir ||
26502                 error "unlink striped dir fails"
26503
26504         return 0
26505 }
26506 run_test 300k "test large striped directory"
26507
26508 test_300l() {
26509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26511         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26512                 skip "Need MDS version at least 2.7.55"
26513
26514         local stripe_index
26515
26516         test_mkdir -p $DIR/$tdir/striped_dir
26517         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26518                         error "chown $RUNAS_ID failed"
26519         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26520                 error "set default striped dir failed"
26521
26522         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26523         $LCTL set_param fail_loc=0x80000158
26524         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26525
26526         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26527         [ $stripe_index -eq 1 ] ||
26528                 error "expect 1 get $stripe_index for $dir"
26529 }
26530 run_test 300l "non-root user to create dir under striped dir with stale layout"
26531
26532 test_300m() {
26533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26534         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26535         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26536                 skip "Need MDS version at least 2.7.55"
26537
26538         mkdir -p $DIR/$tdir/striped_dir
26539         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26540                 error "set default stripes dir error"
26541
26542         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26543
26544         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26545         [ $stripe_count -eq 0 ] ||
26546                         error "expect 0 get $stripe_count for a"
26547
26548         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26549                 error "set default stripes dir error"
26550
26551         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26552
26553         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26554         [ $stripe_count -eq 0 ] ||
26555                         error "expect 0 get $stripe_count for b"
26556
26557         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26558                 error "set default stripes dir error"
26559
26560         mkdir $DIR/$tdir/striped_dir/c &&
26561                 error "default stripe_index is invalid, mkdir c should fails"
26562
26563         rm -rf $DIR/$tdir || error "rmdir fails"
26564 }
26565 run_test 300m "setstriped directory on single MDT FS"
26566
26567 cleanup_300n() {
26568         local list=$(comma_list $(mdts_nodes))
26569
26570         trap 0
26571         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26572 }
26573
26574 test_300n() {
26575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26576         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26577         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26578                 skip "Need MDS version at least 2.7.55"
26579         remote_mds_nodsh && skip "remote MDS with nodsh"
26580
26581         local stripe_index
26582         local list=$(comma_list $(mdts_nodes))
26583
26584         trap cleanup_300n RETURN EXIT
26585         mkdir -p $DIR/$tdir
26586         chmod 777 $DIR/$tdir
26587         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26588                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26589                 error "create striped dir succeeds with gid=0"
26590
26591         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26592         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26593                 error "create striped dir fails with gid=-1"
26594
26595         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26596         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26597                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26598                 error "set default striped dir succeeds with gid=0"
26599
26600
26601         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26602         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26603                 error "set default striped dir fails with gid=-1"
26604
26605
26606         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26607         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26608                                         error "create test_dir fails"
26609         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26610                                         error "create test_dir1 fails"
26611         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26612                                         error "create test_dir2 fails"
26613         cleanup_300n
26614 }
26615 run_test 300n "non-root user to create dir under striped dir with default EA"
26616
26617 test_300o() {
26618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26620         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26621                 skip "Need MDS version at least 2.7.55"
26622
26623         local numfree1
26624         local numfree2
26625
26626         mkdir -p $DIR/$tdir
26627
26628         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26629         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26630         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26631                 skip "not enough free inodes $numfree1 $numfree2"
26632         fi
26633
26634         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26635         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26636         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26637                 skip "not enough free space $numfree1 $numfree2"
26638         fi
26639
26640         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26641                 error "setdirstripe fails"
26642
26643         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26644                 error "create dirs fails"
26645
26646         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26647         ls $DIR/$tdir/striped_dir > /dev/null ||
26648                 error "ls striped dir fails"
26649         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26650                 error "unlink big striped dir fails"
26651 }
26652 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26653
26654 test_300p() {
26655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26657         remote_mds_nodsh && skip "remote MDS with nodsh"
26658
26659         mkdir_on_mdt0 $DIR/$tdir
26660
26661         #define OBD_FAIL_OUT_ENOSPC     0x1704
26662         do_facet mds2 lctl set_param fail_loc=0x80001704
26663         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26664                  && error "create striped directory should fail"
26665
26666         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26667
26668         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26669         true
26670 }
26671 run_test 300p "create striped directory without space"
26672
26673 test_300q() {
26674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26676
26677         local fd=$(free_fd)
26678         local cmd="exec $fd<$tdir"
26679         cd $DIR
26680         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26681         eval $cmd
26682         cmd="exec $fd<&-"
26683         trap "eval $cmd" EXIT
26684         cd $tdir || error "cd $tdir fails"
26685         rmdir  ../$tdir || error "rmdir $tdir fails"
26686         mkdir local_dir && error "create dir succeeds"
26687         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26688         eval $cmd
26689         return 0
26690 }
26691 run_test 300q "create remote directory under orphan directory"
26692
26693 test_300r() {
26694         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26695                 skip "Need MDS version at least 2.7.55" && return
26696         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26697
26698         mkdir $DIR/$tdir
26699
26700         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26701                 error "set striped dir error"
26702
26703         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26704                 error "getstripeddir fails"
26705
26706         local stripe_count
26707         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26708                       awk '/lmv_stripe_count:/ { print $2 }')
26709
26710         [ $MDSCOUNT -ne $stripe_count ] &&
26711                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26712
26713         rm -rf $DIR/$tdir/striped_dir ||
26714                 error "unlink striped dir fails"
26715 }
26716 run_test 300r "test -1 striped directory"
26717
26718 test_300s_helper() {
26719         local count=$1
26720
26721         local stripe_dir=$DIR/$tdir/striped_dir.$count
26722
26723         $LFS mkdir -c $count $stripe_dir ||
26724                 error "lfs mkdir -c error"
26725
26726         $LFS getdirstripe $stripe_dir ||
26727                 error "lfs getdirstripe fails"
26728
26729         local stripe_count
26730         stripe_count=$($LFS getdirstripe $stripe_dir |
26731                       awk '/lmv_stripe_count:/ { print $2 }')
26732
26733         [ $count -ne $stripe_count ] &&
26734                 error_noexit "bad stripe count $stripe_count expected $count"
26735
26736         local dupe_stripes
26737         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26738                 awk '/0x/ {count[$1] += 1}; END {
26739                         for (idx in count) {
26740                                 if (count[idx]>1) {
26741                                         print "index " idx " count " count[idx]
26742                                 }
26743                         }
26744                 }')
26745
26746         if [[ -n "$dupe_stripes" ]] ; then
26747                 lfs getdirstripe $stripe_dir
26748                 error_noexit "Dupe MDT above: $dupe_stripes "
26749         fi
26750
26751         rm -rf $stripe_dir ||
26752                 error_noexit "unlink $stripe_dir fails"
26753 }
26754
26755 test_300s() {
26756         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26757                 skip "Need MDS version at least 2.7.55" && return
26758         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26759
26760         mkdir $DIR/$tdir
26761         for count in $(seq 2 $MDSCOUNT); do
26762                 test_300s_helper $count
26763         done
26764 }
26765 run_test 300s "test lfs mkdir -c without -i"
26766
26767 test_300t() {
26768         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26769                 skip "need MDS 2.14.55 or later"
26770         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26771
26772         local testdir="$DIR/$tdir/striped_dir"
26773         local dir1=$testdir/dir1
26774         local dir2=$testdir/dir2
26775
26776         mkdir -p $testdir
26777
26778         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26779                 error "failed to set default stripe count for $testdir"
26780
26781         mkdir $dir1
26782         local stripe_count=$($LFS getdirstripe -c $dir1)
26783
26784         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26785
26786         local max_count=$((MDSCOUNT - 1))
26787         local mdts=$(comma_list $(mdts_nodes))
26788
26789         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26790         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26791
26792         mkdir $dir2
26793         stripe_count=$($LFS getdirstripe -c $dir2)
26794
26795         (( $stripe_count == $max_count )) || error "wrong stripe count"
26796 }
26797 run_test 300t "test max_mdt_stripecount"
26798
26799 MDT_OVSTRP_VER="2.15.60"
26800 # 300u family tests MDT overstriping
26801 test_300ua() {
26802         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26803
26804         local setcount=$((MDSCOUNT * 2))
26805
26806         local expected_count
26807
26808         mkdir $DIR/$tdir
26809         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26810                 error "(0) failed basic overstriped dir creation test"
26811         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26812
26813         # This does a basic interop test - if the MDS does not support mdt
26814         # overstriping, we should get stripes == number of MDTs
26815         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26816                 expected_count=$MDSCOUNT
26817         else
26818                 expected_count=$setcount
26819         fi
26820         (( getstripe_count == expected_count )) ||
26821                 error "(1) incorrect stripe count for simple overstriped dir"
26822
26823         rm -rf $DIR/$tdir/${tdir}.0 ||
26824                 error "(2) unable to rm overstriped dir"
26825
26826         # Tests after this require overstriping support
26827         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26828                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26829
26830         test_striped_dir 0 $setcount true ||
26831                 error "(3)failed on overstriped dir"
26832         test_striped_dir 1 $setcount true ||
26833                 error "(4)failed on overstriped dir"
26834
26835         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26836
26837         test_striped_dir 0 $setcount true ||
26838                 error "(5)failed on overstriped dir"
26839 }
26840 run_test 300ua "basic overstriped dir sanity test"
26841
26842 test_300ub() {
26843         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26844                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26845         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26846
26847         mkdir $DIR/$tdir
26848
26849         echo "Testing invalid stripe count, failure expected"
26850         local setcount=$((MDSCOUNT * 2))
26851
26852         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26853         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26854
26855         (( getstripe_count <= MDSCOUNT )) ||
26856                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26857
26858         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26859         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26860         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26861
26862         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26863
26864         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26865         (( getstripe_count == maxcount )) ||
26866                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26867
26868         # Test specific striping with -i
26869         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26870
26871         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26872         (( getstripe_count == 4 )) ||
26873                 error "(2)stripe_count is $getstripe_count, expect 4"
26874
26875         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26876                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26877
26878         [[ -n "$nonzeroindices" ]] ||
26879                 error "(3) stripes indices not all 0: $nonzeroindices"
26880
26881         # Test specific striping with too many stripes on one MDT
26882         echo "Testing invalid striping, failure expected"
26883         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26884         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26885         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26886                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26887         echo "stripes on MDT0: $getstripe_count"
26888         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26889                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26890
26891         setcount=$((MDSCOUNT * 2))
26892         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26893                 error "(5) can't setdirstripe with manually set hash function"
26894
26895         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26896         (( getstripe_count == setcount )) ||
26897                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26898
26899         setcount=$((MDSCOUNT * 2))
26900         mkdir $DIR/${tdir}.5
26901         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26902                 error "(7) can't setdirstripe with manually set hash function"
26903         mkdir $DIR/${tdir}.5/${tdir}.6
26904
26905         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26906         (( getstripe_count == setcount )) ||
26907                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26908 }
26909 run_test 300ub "test MDT overstriping interface & limits"
26910
26911 test_300uc() {
26912         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26913                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26914         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26915
26916         mkdir $DIR/$tdir
26917
26918         local setcount=$((MDSCOUNT * 2))
26919
26920         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26921
26922         mkdir $DIR/$tdir/${tdir}.1
26923
26924         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26925
26926         (( getstripe_count == setcount )) ||
26927                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26928
26929         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26930
26931         local getstripe_count=$($LFS getdirstripe -c \
26932                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26933
26934         (( getstripe_count == setcount )) ||
26935                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26936 }
26937 run_test 300uc "test MDT overstriping as default & inheritance"
26938
26939 test_300ud() {
26940         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26941                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26942         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26943
26944         local mdts=$(comma_list $(mdts_nodes))
26945         local timeout=100
26946
26947         local restripe_status
26948         local delta
26949         local i
26950
26951         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26952
26953         # in case "crush" hash type is not set
26954         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26955
26956         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26957                            mdt.*MDT0000.enable_dir_restripe)
26958         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26959         stack_trap "do_nodes $mdts $LCTL set_param \
26960                     mdt.*.enable_dir_restripe=$restripe_status"
26961
26962         mkdir $DIR/$tdir
26963         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26964                 error "create files under remote dir failed $i"
26965         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26966                 error "create dirs under remote dir failed $i"
26967
26968         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26969
26970         (( setcount < 13 )) || setcount=12
26971         for i in $(seq 2 $setcount); do
26972                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26973                 $LFS setdirstripe -C $i $DIR/$tdir ||
26974                         error "split -C $i $tdir failed"
26975                 wait_update $HOSTNAME \
26976                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26977                         error "dir split not finished"
26978                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26979                         awk '/migrate/ {sum += $2} END { print sum }')
26980                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26981                 # delta is around total_files/stripe_count, deviation 3%
26982                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26983                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26984         done
26985 }
26986 run_test 300ud "dir split"
26987
26988 test_300ue() {
26989         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26990                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26991         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26992
26993         local mdts=$(comma_list $(mdts_nodes))
26994         local timeout=100
26995
26996         local restripe_status
26997         local delta
26998         local c
26999
27000         [[ $mds1_FSTYPE == zfs ]] && timeout=300
27001
27002         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
27003
27004         restripe_status=$(do_facet mds1 $LCTL get_param -n \
27005                            mdt.*MDT0000.enable_dir_restripe)
27006         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
27007         stack_trap "do_nodes $mdts $LCTL set_param \
27008                     mdt.*.enable_dir_restripe=$restripe_status"
27009
27010         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27011
27012         (( setcount < 13 )) || setcount=12
27013         test_mkdir -C $setcount -H crush $DIR/$tdir
27014         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
27015                 error "create files under remote dir failed"
27016         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
27017                 error "create dirs under remote dir failed"
27018
27019         for c in $(seq $((setcount - 1)) -1 1); do
27020                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
27021                 $LFS setdirstripe -C $c $DIR/$tdir ||
27022                         error "split -C $c $tdir failed"
27023                 wait_update $HOSTNAME \
27024                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
27025                         error "dir merge not finished"
27026                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
27027                         awk '/migrate/ {sum += $2} END { print sum }')
27028                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
27029                 # delta is around total_files/stripe_count, deviation 3%
27030                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
27031                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
27032         done
27033 }
27034 run_test 300ue "dir merge"
27035
27036 test_300uf() {
27037         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
27038                 skip "skipped for MDS < $MDT_OVSTRP_VER"
27039         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27040
27041         # maximum amount of local locks:
27042         # parent striped dir - 2 locks
27043         # new stripe in parent to migrate to - 1 lock
27044         # source and target - 2 locks
27045         # Total 5 locks for regular file
27046         #
27047         # NB: Overstriping should add several extra local locks
27048         # FIXME: Remove this once understood
27049         #lctl set_param *debug=-1 debug_mb=10000
27050         lctl clear
27051         lctl mark "touch/create"
27052         mkdir -p $DIR/$tdir
27053         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27054         local setcount=$((MDSCOUNT * 5))
27055
27056         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
27057         touch $DIR/$tdir/dir1/eee
27058
27059         lctl mark "hardlinks"
27060         # create 4 hardlink for 4 more locks
27061         # Total: 9 locks > RS_MAX_LOCKS (8)
27062         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
27063         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
27064         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
27065         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
27066         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
27067         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
27068         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
27069         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
27070
27071         lctl mark "cancel lru"
27072         cancel_lru_locks mdc
27073
27074         lctl mark "migrate"
27075         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
27076                 error "migrate dir fails"
27077
27078         rm -rf $DIR/$tdir || error "rm dir failed after migration"
27079 }
27080 run_test 300uf "migrate with too many local locks"
27081
27082 test_300ug() {
27083         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
27084                 skip "skipped for MDS < $MDT_OVSTRP_VER"
27085         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27086
27087         mkdir -p $DIR/$tdir
27088         local migrate_dir=$DIR/$tdir/migrate_dir
27089         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27090         local setcount2=$((setcount - 2))
27091
27092         $LFS setdirstripe -c 2 $migrate_dir ||
27093                 error "(0) failed to create striped directory"
27094
27095         $LFS migrate -m 0 -C $setcount $migrate_dir ||
27096                 error "(1)failed to migrate to overstriped directory"
27097         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27098
27099         (( getstripe_count == setcount )) ||
27100                 error "(2)stripe_count is $getstripe_count, expect $setcount"
27101         touch $DIR/$tdir/migrate_dir/$tfile ||
27102                 error "(3)failed to create file in overstriped directory"
27103         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
27104                 error "(4)failed to migrate overstriped directory"
27105         # Check stripe count after migration
27106         $LFS getdirstripe $migrate_dir
27107         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27108         (( getstripe_count == setcount2 )) ||
27109                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
27110
27111         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
27112 }
27113 run_test 300ug "migrate overstriped dirs"
27114
27115 prepare_remote_file() {
27116         mkdir $DIR/$tdir/src_dir ||
27117                 error "create remote source failed"
27118
27119         cp /etc/hosts $DIR/$tdir/src_dir/a ||
27120                  error "cp to remote source failed"
27121         touch $DIR/$tdir/src_dir/a
27122
27123         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
27124                 error "create remote target dir failed"
27125
27126         touch $DIR/$tdir/tgt_dir/b
27127
27128         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
27129                 error "rename dir cross MDT failed!"
27130
27131         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
27132                 error "src_child still exists after rename"
27133
27134         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
27135                 error "missing file(a) after rename"
27136
27137         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
27138                 error "diff after rename"
27139 }
27140
27141 test_310a() {
27142         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27144
27145         local remote_file=$DIR/$tdir/tgt_dir/b
27146
27147         mkdir -p $DIR/$tdir
27148
27149         prepare_remote_file || error "prepare remote file failed"
27150
27151         #open-unlink file
27152         $OPENUNLINK $remote_file $remote_file ||
27153                 error "openunlink $remote_file failed"
27154         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27155 }
27156 run_test 310a "open unlink remote file"
27157
27158 test_310b() {
27159         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27161
27162         local remote_file=$DIR/$tdir/tgt_dir/b
27163
27164         mkdir -p $DIR/$tdir
27165
27166         prepare_remote_file || error "prepare remote file failed"
27167
27168         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27169         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27170         $CHECKSTAT -t file $remote_file || error "check file failed"
27171 }
27172 run_test 310b "unlink remote file with multiple links while open"
27173
27174 test_310c() {
27175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27176         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27177
27178         local remote_file=$DIR/$tdir/tgt_dir/b
27179
27180         mkdir -p $DIR/$tdir
27181
27182         prepare_remote_file || error "prepare remote file failed"
27183
27184         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27185         multiop_bg_pause $remote_file O_uc ||
27186                         error "mulitop failed for remote file"
27187         MULTIPID=$!
27188         $MULTIOP $DIR/$tfile Ouc
27189         kill -USR1 $MULTIPID
27190         wait $MULTIPID
27191 }
27192 run_test 310c "open-unlink remote file with multiple links"
27193
27194 #LU-4825
27195 test_311() {
27196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27197         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27198         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27199                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27200         remote_mds_nodsh && skip "remote MDS with nodsh"
27201
27202         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27203         local mdts=$(comma_list $(mdts_nodes))
27204
27205         mkdir -p $DIR/$tdir
27206         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27207         createmany -o $DIR/$tdir/$tfile. 1000
27208
27209         # statfs data is not real time, let's just calculate it
27210         old_iused=$((old_iused + 1000))
27211
27212         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27213                         osp.*OST0000*MDT0000.create_count")
27214         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27215                                 osp.*OST0000*MDT0000.max_create_count")
27216         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27217
27218         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27219         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27220         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27221
27222         unlinkmany $DIR/$tdir/$tfile. 1000
27223
27224         do_nodes $mdts "$LCTL set_param -n \
27225                         osp.*OST0000*.max_create_count=$max_count"
27226         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27227                 do_nodes $mdts "$LCTL set_param -n \
27228                                 osp.*OST0000*.create_count=$count"
27229         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27230                         grep "=0" && error "create_count is zero"
27231
27232         local new_iused
27233         for i in $(seq 120); do
27234                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27235                 # system may be too busy to destroy all objs in time, use
27236                 # a somewhat small value to not fail autotest
27237                 [ $((old_iused - new_iused)) -gt 400 ] && break
27238                 sleep 1
27239         done
27240
27241         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27242         [ $((old_iused - new_iused)) -gt 400 ] ||
27243                 error "objs not destroyed after unlink"
27244 }
27245 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27246
27247 zfs_get_objid()
27248 {
27249         local ost=$1
27250         local tf=$2
27251         local fid=($($LFS getstripe $tf | grep 0x))
27252         local seq=${fid[3]#0x}
27253         local objid=${fid[1]}
27254
27255         local vdevdir=$(dirname $(facet_vdevice $ost))
27256         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27257         local zfs_zapid=$(do_facet $ost $cmd |
27258                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27259                           awk '/Object/{getline; print $1}')
27260         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27261                           awk "/$objid = /"'{printf $3}')
27262
27263         echo $zfs_objid
27264 }
27265
27266 zfs_object_blksz() {
27267         local ost=$1
27268         local objid=$2
27269
27270         local vdevdir=$(dirname $(facet_vdevice $ost))
27271         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27272         local blksz=$(do_facet $ost $cmd $objid |
27273                       awk '/dblk/{getline; printf $4}')
27274
27275         case "${blksz: -1}" in
27276                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27277                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27278                 *) ;;
27279         esac
27280
27281         echo $blksz
27282 }
27283
27284 test_312() { # LU-4856
27285         remote_ost_nodsh && skip "remote OST with nodsh"
27286         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27287
27288         local max_blksz=$(do_facet ost1 \
27289                           $ZFS get -p recordsize $(facet_device ost1) |
27290                           awk '!/VALUE/{print $3}')
27291         local tf=$DIR/$tfile
27292
27293         $LFS setstripe -c1 $tf
27294         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27295
27296         # Get ZFS object id
27297         local zfs_objid=$(zfs_get_objid $facet $tf)
27298         # block size change by sequential overwrite
27299         local bs
27300
27301         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27302                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27303
27304                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27305                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27306         done
27307         rm -f $tf
27308
27309         $LFS setstripe -c1 $tf
27310         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27311
27312         # block size change by sequential append write
27313         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27314         zfs_objid=$(zfs_get_objid $facet $tf)
27315         local count
27316
27317         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27318                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27319                         oflag=sync conv=notrunc
27320
27321                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27322                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27323                         error "blksz error, actual $blksz, " \
27324                                 "expected: 2 * $count * $PAGE_SIZE"
27325         done
27326         rm -f $tf
27327
27328         # random write
27329         $LFS setstripe -c1 $tf
27330         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27331         zfs_objid=$(zfs_get_objid $facet $tf)
27332
27333         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27334         blksz=$(zfs_object_blksz $facet $zfs_objid)
27335         (( blksz == PAGE_SIZE )) ||
27336                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27337
27338         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27339         blksz=$(zfs_object_blksz $facet $zfs_objid)
27340         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27341
27342         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27343         blksz=$(zfs_object_blksz $facet $zfs_objid)
27344         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27345 }
27346 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27347
27348 test_313() {
27349         remote_ost_nodsh && skip "remote OST with nodsh"
27350
27351         local file=$DIR/$tfile
27352
27353         rm -f $file
27354         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27355
27356         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27357         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27358         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27359                 error "write should failed"
27360         do_facet ost1 "$LCTL set_param fail_loc=0"
27361         rm -f $file
27362 }
27363 run_test 313 "io should fail after last_rcvd update fail"
27364
27365 test_314() {
27366         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27367
27368         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27369         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27370         rm -f $DIR/$tfile
27371         wait_delete_completed
27372         do_facet ost1 "$LCTL set_param fail_loc=0"
27373 }
27374 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27375
27376 test_315() { # LU-618
27377         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27378
27379         local file=$DIR/$tfile
27380         rm -f $file
27381
27382         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27383                 error "multiop file write failed"
27384         $MULTIOP $file oO_RDONLY:r4063232_c &
27385         PID=$!
27386
27387         sleep 2
27388
27389         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27390         kill -USR1 $PID
27391
27392         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27393         rm -f $file
27394 }
27395 run_test 315 "read should be accounted"
27396
27397 test_316() {
27398         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27399         large_xattr_enabled || skip "ea_inode feature disabled"
27400
27401         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27402         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27403         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27404         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27405
27406         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27407 }
27408 run_test 316 "lfs migrate of file with large_xattr enabled"
27409
27410 test_317() {
27411         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27412                 skip "Need MDS version at least 2.11.53"
27413         if [ "$ost1_FSTYPE" == "zfs" ]; then
27414                 skip "LU-10370: no implementation for ZFS"
27415         fi
27416
27417         local trunc_sz
27418         local grant_blk_size
27419
27420         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27421                         awk '/grant_block_size:/ { print $2; exit; }')
27422         #
27423         # Create File of size 5M. Truncate it to below size's and verify
27424         # blocks count.
27425         #
27426         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27427                 error "Create file $DIR/$tfile failed"
27428         stack_trap "rm -f $DIR/$tfile" EXIT
27429
27430         for trunc_sz in 2097152 4097 4000 509 0; do
27431                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27432                         error "truncate $tfile to $trunc_sz failed"
27433                 local sz=$(stat --format=%s $DIR/$tfile)
27434                 local blk=$(stat --format=%b $DIR/$tfile)
27435                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27436                                      grant_blk_size) * 8))
27437
27438                 if [[ $blk -ne $trunc_blk ]]; then
27439                         $(which stat) $DIR/$tfile
27440                         error "Expected Block $trunc_blk got $blk for $tfile"
27441                 fi
27442
27443                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27444                         error "Expected Size $trunc_sz got $sz for $tfile"
27445         done
27446
27447         #
27448         # sparse file test
27449         # Create file with a hole and write actual 65536 bytes which aligned
27450         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27451         #
27452         local bs=65536
27453         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27454                 error "Create file : $DIR/$tfile"
27455
27456         #
27457         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27458         # blocks. The block count must drop to 8.
27459         #
27460         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27461                 ((bs - grant_blk_size) + 1)))
27462         $TRUNCATE $DIR/$tfile $trunc_sz ||
27463                 error "truncate $tfile to $trunc_sz failed"
27464
27465         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27466         sz=$(stat --format=%s $DIR/$tfile)
27467         blk=$(stat --format=%b $DIR/$tfile)
27468
27469         if [[ $blk -ne $trunc_bsz ]]; then
27470                 $(which stat) $DIR/$tfile
27471                 error "Expected Block $trunc_bsz got $blk for $tfile"
27472         fi
27473
27474         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27475                 error "Expected Size $trunc_sz got $sz for $tfile"
27476 }
27477 run_test 317 "Verify blocks get correctly update after truncate"
27478
27479 test_318() {
27480         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27481         local old_max_active=$($LCTL get_param -n \
27482                             ${llite_name}.max_read_ahead_async_active \
27483                             2>/dev/null)
27484
27485         $LCTL set_param llite.*.max_read_ahead_async_active=256
27486         local max_active=$($LCTL get_param -n \
27487                            ${llite_name}.max_read_ahead_async_active \
27488                            2>/dev/null)
27489         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27490
27491         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27492                 error "set max_read_ahead_async_active should succeed"
27493
27494         $LCTL set_param llite.*.max_read_ahead_async_active=512
27495         max_active=$($LCTL get_param -n \
27496                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27497         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27498
27499         # restore @max_active
27500         [ $old_max_active -ne 0 ] && $LCTL set_param \
27501                 llite.*.max_read_ahead_async_active=$old_max_active
27502
27503         local old_threshold=$($LCTL get_param -n \
27504                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27505         local max_per_file_mb=$($LCTL get_param -n \
27506                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27507
27508         local invalid=$(($max_per_file_mb + 1))
27509         $LCTL set_param \
27510                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27511                         && error "set $invalid should fail"
27512
27513         local valid=$(($invalid - 1))
27514         $LCTL set_param \
27515                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27516                         error "set $valid should succeed"
27517         local threshold=$($LCTL get_param -n \
27518                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27519         [ $threshold -eq $valid ] || error \
27520                 "expect threshold $valid got $threshold"
27521         $LCTL set_param \
27522                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27523 }
27524 run_test 318 "Verify async readahead tunables"
27525
27526 test_319() {
27527         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27528
27529         local before=$(date +%s)
27530         local evict
27531         local mdir=$DIR/$tdir
27532         local file=$mdir/xxx
27533
27534         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27535         touch $file
27536
27537 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27538         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27539         $LFS migrate -m1 $mdir &
27540
27541         sleep 1
27542         dd if=$file of=/dev/null
27543         wait
27544         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27545           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27546
27547         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27548 }
27549 run_test 319 "lost lease lock on migrate error"
27550
27551 test_350() {
27552         local mdts=$(comma_list $(mdts_nodes))
27553
27554         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27555         stack_trap "rm -r $DIR/$tdir"
27556
27557         #force 1/100 of replies to take "NID mismatch" codepath
27558         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27559         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27560
27561         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27562         stack_trap "killall -9 ls || killall -9 ls"
27563
27564         cp -a /etc $DIR/$tdir || error "cp failed"
27565 }
27566 run_test 350 "force NID mismatch path to be exercised"
27567
27568 test_360() {
27569         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27570                 skip "Need OST version at least 2.15.58.96"
27571         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27572
27573         check_set_fallocate_or_skip
27574         local param="osd-ldiskfs.delayed_unlink_mb"
27575         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27576
27577         do_facet ost1 "$LCTL set_param $param=1MiB"
27578         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27579
27580         mkdir $DIR/$tdir/
27581         do_facet ost1 $LCTL set_param debug=+inode
27582         do_facet ost1 $LCTL clear
27583         local files=100
27584
27585         for ((i = 0; i < $files; i++)); do
27586                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27587                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27588         done
27589         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27590
27591         for ((i = 0; i < $files; i++)); do
27592                 unlink $DIR/$tdir/$tfile.$i ||
27593                         error "unlink $DIR/$tdir/$tfile.$i failed"
27594         done
27595
27596         local count=0
27597         local loop
27598
27599         for (( loop = 0; loop < 30 && count < min; loop++)); do
27600                 sleep 1
27601                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27602                 echo "Count[$loop]: $count"
27603         done
27604         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27605 }
27606 run_test 360 "ldiskfs unlink in a separate thread"
27607
27608 test_398a() { # LU-4198
27609         local ost1_imp=$(get_osc_import_name client ost1)
27610         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27611                          cut -d'.' -f2)
27612
27613         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27614         stack_trap "rm -f $DIR/$tfile"
27615         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27616
27617         # request a new lock on client
27618         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27619
27620         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27621         local lock_count=$($LCTL get_param -n \
27622                            ldlm.namespaces.$imp_name.lru_size)
27623         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27624
27625         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27626
27627         # no lock cached, should use lockless DIO and not enqueue new lock
27628         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27629         lock_count=$($LCTL get_param -n \
27630                      ldlm.namespaces.$imp_name.lru_size)
27631         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27632
27633         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27634
27635         # no lock cached, should use locked DIO append
27636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27637                 conv=notrunc || error "DIO append failed"
27638         lock_count=$($LCTL get_param -n \
27639                      ldlm.namespaces.$imp_name.lru_size)
27640         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27641 }
27642 run_test 398a "direct IO should cancel lock otherwise lockless"
27643
27644 test_398b() { # LU-4198
27645         local before=$(date +%s)
27646         local njobs=4
27647         local size=48
27648
27649         which fio || skip_env "no fio installed"
27650         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27651         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27652
27653         # Single page, multiple pages, stripe size, 4*stripe size
27654         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27655                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27656                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27657                         --numjobs=$njobs --fallocate=none \
27658                         --iodepth=16 --allow_file_create=0 \
27659                         --size=$((size/njobs))M \
27660                         --filename=$DIR/$tfile &
27661                 bg_pid=$!
27662
27663                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27664                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27665                         --numjobs=$njobs --fallocate=none \
27666                         --iodepth=16 --allow_file_create=0 \
27667                         --size=$((size/njobs))M \
27668                         --filename=$DIR/$tfile || true
27669                 wait $bg_pid
27670         done
27671
27672         evict=$(do_facet client $LCTL get_param \
27673                 osc.$FSNAME-OST*-osc-*/state |
27674             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27675
27676         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27677                 (do_facet client $LCTL get_param \
27678                         osc.$FSNAME-OST*-osc-*/state;
27679                     error "eviction happened: $evict before:$before")
27680
27681         rm -f $DIR/$tfile
27682 }
27683 run_test 398b "DIO and buffer IO race"
27684
27685 test_398c() { # LU-4198
27686         local ost1_imp=$(get_osc_import_name client ost1)
27687         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27688                          cut -d'.' -f2)
27689
27690         which fio || skip_env "no fio installed"
27691
27692         saved_debug=$($LCTL get_param -n debug)
27693         $LCTL set_param debug=0
27694
27695         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27696         ((size /= 1024)) # by megabytes
27697         ((size /= 2)) # write half of the OST at most
27698         [ $size -gt 40 ] && size=40 #reduce test time anyway
27699
27700         $LFS setstripe -c 1 $DIR/$tfile
27701
27702         # it seems like ldiskfs reserves more space than necessary if the
27703         # writing blocks are not mapped, so it extends the file firstly
27704         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27705         cancel_lru_locks osc
27706
27707         # clear and verify rpc_stats later
27708         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27709
27710         local njobs=4
27711         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27712         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27713                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27714                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27715                 --filename=$DIR/$tfile
27716         [ $? -eq 0 ] || error "fio write error"
27717
27718         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27719                 error "Locks were requested while doing AIO"
27720
27721         # get the percentage of 1-page I/O
27722         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27723                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27724                 awk '{print $7}')
27725         (( $pct <= 50 )) || {
27726                 $LCTL get_param osc.${imp_name}.rpc_stats
27727                 error "$pct% of I/O are 1-page"
27728         }
27729
27730         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27731         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27732                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27733                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27734                 --filename=$DIR/$tfile
27735         [ $? -eq 0 ] || error "fio mixed read write error"
27736
27737         echo "AIO with large block size ${size}M"
27738         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27739                 --numjobs=1 --fallocate=none --ioengine=libaio \
27740                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27741                 --filename=$DIR/$tfile
27742         [ $? -eq 0 ] || error "fio large block size failed"
27743
27744         rm -f $DIR/$tfile
27745         $LCTL set_param debug="$saved_debug"
27746 }
27747 run_test 398c "run fio to test AIO"
27748
27749 test_398d() { #  LU-13846
27750         which aiocp || skip_env "no aiocp installed"
27751         local aio_file=$DIR/$tfile.aio
27752
27753         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27754
27755         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27756         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27757         stack_trap "rm -f $DIR/$tfile $aio_file"
27758
27759         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27760
27761         # test memory unaligned aio
27762         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27763                 error "unaligned aio failed"
27764         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27765
27766         rm -f $DIR/$tfile $aio_file
27767 }
27768 run_test 398d "run aiocp to verify block size > stripe size"
27769
27770 test_398e() {
27771         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27772         touch $DIR/$tfile.new
27773         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27774 }
27775 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27776
27777 test_398f() { #  LU-14687
27778         which aiocp || skip_env "no aiocp installed"
27779         local aio_file=$DIR/$tfile.aio
27780
27781         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27782
27783         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27784         stack_trap "rm -f $DIR/$tfile $aio_file"
27785
27786         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27787         $LCTL set_param fail_loc=0x1418
27788         # make sure we don't crash and fail properly
27789         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27790                 error "aio with page allocation failure succeeded"
27791         $LCTL set_param fail_loc=0
27792         diff $DIR/$tfile $aio_file
27793         [[ $? != 0 ]] || error "no diff after failed aiocp"
27794 }
27795 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27796
27797 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27798 # stripe and i/o size must be > stripe size
27799 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27800 # single RPC in flight.  This test shows async DIO submission is working by
27801 # showing multiple RPCs in flight.
27802 test_398g() { #  LU-13798
27803         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27804
27805         # We need to do some i/o first to acquire enough grant to put our RPCs
27806         # in flight; otherwise a new connection may not have enough grant
27807         # available
27808         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27809                 error "parallel dio failed"
27810         stack_trap "rm -f $DIR/$tfile"
27811
27812         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27813         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27814         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27815         stack_trap "$LCTL set_param -n $pages_per_rpc"
27816
27817         # Recreate file so it's empty
27818         rm -f $DIR/$tfile
27819         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27820         #Pause rpc completion to guarantee we see multiple rpcs in flight
27821         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27822         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27823         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27824
27825         # Clear rpc stats
27826         $LCTL set_param osc.*.rpc_stats=c
27827
27828         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27829                 error "parallel dio failed"
27830         stack_trap "rm -f $DIR/$tfile"
27831
27832         $LCTL get_param osc.*-OST0000-*.rpc_stats
27833         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27834                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27835                 grep "8:" | awk '{print $8}')
27836         # We look at the "8 rpcs in flight" field, and verify A) it is present
27837         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27838         # as expected for an 8M DIO to a file with 1M stripes.
27839         # NB: There is occasionally a mystery extra write RPC to a different
27840         # file.  I can't identify why that's happening, so we set up a margin
27841         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27842         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27843
27844         # Verify turning off parallel dio works as expected
27845         # Clear rpc stats
27846         $LCTL set_param osc.*.rpc_stats=c
27847         $LCTL set_param llite.*.parallel_dio=0
27848         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27849
27850         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27851                 error "dio with parallel dio disabled failed"
27852
27853         # Ideally, we would see only one RPC in flight here, but there is an
27854         # unavoidable race between i/o completion and RPC in flight counting,
27855         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27856         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27857         # So instead we just verify it's always < 8.
27858         $LCTL get_param osc.*-OST0000-*.rpc_stats
27859         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27860                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27861                 grep '^$' -B1 | grep . | awk '{print $1}')
27862         [ $ret != "8:" ] ||
27863                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27864 }
27865 run_test 398g "verify parallel dio async RPC submission"
27866
27867 test_398h() { #  LU-13798
27868         local dio_file=$DIR/$tfile.dio
27869
27870         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27871
27872         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27873         stack_trap "rm -f $DIR/$tfile $dio_file"
27874
27875         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27876                 error "parallel dio failed"
27877         diff $DIR/$tfile $dio_file
27878         [[ $? == 0 ]] || error "file diff after aiocp"
27879 }
27880 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27881
27882 test_398i() { #  LU-13798
27883         local dio_file=$DIR/$tfile.dio
27884
27885         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27886
27887         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27888         stack_trap "rm -f $DIR/$tfile $dio_file"
27889
27890         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27891         $LCTL set_param fail_loc=0x1418
27892         # make sure we don't crash and fail properly
27893         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27894                 error "parallel dio page allocation failure succeeded"
27895         diff $DIR/$tfile $dio_file
27896         [[ $? != 0 ]] || error "no diff after failed aiocp"
27897 }
27898 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27899
27900 test_398j() { #  LU-13798
27901         # Stripe size > RPC size but less than i/o size tests split across
27902         # stripes and RPCs for individual i/o op
27903         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27904
27905         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27906         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27907         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27908         stack_trap "$LCTL set_param -n $pages_per_rpc"
27909
27910         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27911                 error "parallel dio write failed"
27912         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27913
27914         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27915                 error "parallel dio read failed"
27916         diff $DIR/$tfile $DIR/$tfile.2
27917         [[ $? == 0 ]] || error "file diff after parallel dio read"
27918 }
27919 run_test 398j "test parallel dio where stripe size > rpc_size"
27920
27921 test_398k() { #  LU-13798
27922         wait_delete_completed
27923         wait_mds_ost_sync
27924
27925         # 4 stripe file; we will cause out of space on OST0
27926         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27927
27928         # Fill OST0 (if it's not too large)
27929         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27930                    head -n1)
27931         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27932                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27933         fi
27934         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27935         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27936                 error "dd should fill OST0"
27937         stack_trap "rm -f $DIR/$tfile.1"
27938
27939         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27940         err=$?
27941
27942         ls -la $DIR/$tfile
27943         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27944                 error "file is not 0 bytes in size"
27945
27946         # dd above should not succeed, but don't error until here so we can
27947         # get debug info above
27948         [[ $err != 0 ]] ||
27949                 error "parallel dio write with enospc succeeded"
27950         stack_trap "rm -f $DIR/$tfile"
27951 }
27952 run_test 398k "test enospc on first stripe"
27953
27954 test_398l() { #  LU-13798
27955         wait_delete_completed
27956         wait_mds_ost_sync
27957
27958         # 4 stripe file; we will cause out of space on OST0
27959         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27960         # happens on the second i/o chunk we issue
27961         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27962
27963         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27964         stack_trap "rm -f $DIR/$tfile"
27965
27966         # Fill OST0 (if it's not too large)
27967         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27968                    head -n1)
27969         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27970                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27971         fi
27972         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27973         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27974                 error "dd should fill OST0"
27975         stack_trap "rm -f $DIR/$tfile.1"
27976
27977         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27978         err=$?
27979         stack_trap "rm -f $DIR/$tfile.2"
27980
27981         # Check that short write completed as expected
27982         ls -la $DIR/$tfile.2
27983         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27984                 error "file is not 1M in size"
27985
27986         # dd above should not succeed, but don't error until here so we can
27987         # get debug info above
27988         [[ $err != 0 ]] ||
27989                 error "parallel dio write with enospc succeeded"
27990
27991         # Truncate source file to same length as output file and diff them
27992         $TRUNCATE $DIR/$tfile 1048576
27993         diff $DIR/$tfile $DIR/$tfile.2
27994         [[ $? == 0 ]] || error "data incorrect after short write"
27995 }
27996 run_test 398l "test enospc on intermediate stripe/RPC"
27997
27998 test_398m() { #  LU-13798
27999         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
28000
28001         # Set up failure on OST0, the first stripe:
28002         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
28003         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
28004         # OST0 is on ost1, OST1 is on ost2.
28005         # So this fail_val specifies OST0
28006         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
28007         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
28008
28009         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
28010                 error "parallel dio write with failure on first stripe succeeded"
28011         stack_trap "rm -f $DIR/$tfile"
28012         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
28013
28014         # Place data in file for read
28015         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
28016                 error "parallel dio write failed"
28017
28018         # Fail read on OST0, first stripe
28019         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28020         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
28021         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
28022                 error "parallel dio read with error on first stripe succeeded"
28023         rm -f $DIR/$tfile.2
28024         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
28025
28026         # Switch to testing on OST1, second stripe
28027         # Clear file contents, maintain striping
28028         echo > $DIR/$tfile
28029         # Set up failure on OST1, second stripe:
28030         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
28031         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
28032
28033         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
28034                 error "parallel dio write with failure on second stripe succeeded"
28035         stack_trap "rm -f $DIR/$tfile"
28036         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
28037
28038         # Place data in file for read
28039         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
28040                 error "parallel dio write failed"
28041
28042         # Fail read on OST1, second stripe
28043         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28044         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
28045         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
28046                 error "parallel dio read with error on second stripe succeeded"
28047         rm -f $DIR/$tfile.2
28048         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
28049 }
28050 run_test 398m "test RPC failures with parallel dio"
28051
28052 # Parallel submission of DIO should not cause problems for append, but it's
28053 # important to verify.
28054 test_398n() { #  LU-13798
28055         $LFS setstripe -C 2 -S 1M $DIR/$tfile
28056
28057         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
28058                 error "dd to create source file failed"
28059         stack_trap "rm -f $DIR/$tfile"
28060
28061         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
28062                 error "parallel dio write with failure on second stripe succeeded"
28063         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
28064         diff $DIR/$tfile $DIR/$tfile.1
28065         [[ $? == 0 ]] || error "data incorrect after append"
28066
28067 }
28068 run_test 398n "test append with parallel DIO"
28069
28070 test_398o() {
28071         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
28072 }
28073 run_test 398o "right kms with DIO"
28074
28075 test_398p()
28076 {
28077         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28078         which aiocp || skip_env "no aiocp installed"
28079
28080         local stripe_size=$((1024 * 1024)) #1 MiB
28081         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28082         local file_size=$((25 * stripe_size))
28083
28084         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28085         stack_trap "rm -f $DIR/$tfile*"
28086         # Just a bit bigger than the largest size in the test set below
28087         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28088                 error "buffered i/o to create file failed"
28089
28090         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28091                 $((stripe_size * 4)); do
28092
28093                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28094
28095                 echo "bs: $bs, file_size $file_size"
28096                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
28097                         $DIR/$tfile.1 $DIR/$tfile.2 &
28098                 pid_dio1=$!
28099                 # Buffered I/O with similar but not the same block size
28100                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28101                         conv=notrunc &
28102                 pid_bio2=$!
28103                 wait $pid_dio1
28104                 rc1=$?
28105                 wait $pid_bio2
28106                 rc2=$?
28107                 if (( rc1 != 0 )); then
28108                         error "aio copy 1 w/bsize $bs failed: $rc1"
28109                 fi
28110                 if (( rc2 != 0 )); then
28111                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28112                 fi
28113
28114                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28115                         error "size incorrect"
28116                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
28117                         error "files differ, bsize $bs"
28118                 rm -f $DIR/$tfile.2
28119         done
28120 }
28121 run_test 398p "race aio with buffered i/o"
28122
28123 test_398q()
28124 {
28125         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28126
28127         local stripe_size=$((1024 * 1024)) #1 MiB
28128         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28129         local file_size=$((25 * stripe_size))
28130
28131         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28132         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28133
28134         # Just a bit bigger than the largest size in the test set below
28135         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28136                 error "buffered i/o to create file failed"
28137
28138         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28139                 $((stripe_size * 4)); do
28140
28141                 echo "bs: $bs, file_size $file_size"
28142                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
28143                         conv=notrunc oflag=direct iflag=direct &
28144                 pid_dio1=$!
28145                 # Buffered I/O with similar but not the same block size
28146                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28147                         conv=notrunc &
28148                 pid_bio2=$!
28149                 wait $pid_dio1
28150                 rc1=$?
28151                 wait $pid_bio2
28152                 rc2=$?
28153                 if (( rc1 != 0 )); then
28154                         error "dio copy 1 w/bsize $bs failed: $rc1"
28155                 fi
28156                 if (( rc2 != 0 )); then
28157                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28158                 fi
28159
28160                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28161                         error "size incorrect"
28162                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28163                         error "files differ, bsize $bs"
28164         done
28165
28166         rm -f $DIR/$tfile*
28167 }
28168 run_test 398q "race dio with buffered i/o"
28169
28170 test_398r() {
28171         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28172         echo "hello, world" > $DIR/$tfile
28173
28174         cancel_lru_locks osc
28175
28176 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28177         do_facet ost1 $LCTL set_param fail_loc=0x20f
28178         cat $DIR/$tfile > /dev/null && error "cat should fail"
28179         return 0
28180 }
28181 run_test 398r "i/o error on file read"
28182
28183 test_398s() {
28184         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28185                 skip "remote OST"
28186
28187         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28188                 error "mirror create failed"
28189
28190         echo "hello, world" > $DIR/$tfile
28191         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28192
28193         cancel_lru_locks osc
28194
28195 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28196         do_facet ost1 $LCTL set_param fail_loc=0x20f
28197         cat $DIR/$tfile > /dev/null && error "cat should fail"
28198         return 0
28199 }
28200 run_test 398s "i/o error on mirror file read"
28201
28202 test_fake_rw() {
28203         local read_write=$1
28204         if [ "$read_write" = "write" ]; then
28205                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28206         elif [ "$read_write" = "read" ]; then
28207                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28208         else
28209                 error "argument error"
28210         fi
28211
28212         # turn off debug for performance testing
28213         local saved_debug=$($LCTL get_param -n debug)
28214         $LCTL set_param debug=0
28215
28216         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28217
28218         # get ost1 size - $FSNAME-OST0000
28219         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28220         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28221         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28222
28223         if [ "$read_write" = "read" ]; then
28224                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28225         fi
28226
28227         local start_time=$(date +%s.%N)
28228         $dd_cmd bs=1M count=$blocks oflag=sync ||
28229                 error "real dd $read_write error"
28230         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28231
28232         if [ "$read_write" = "write" ]; then
28233                 rm -f $DIR/$tfile
28234         fi
28235
28236         # define OBD_FAIL_OST_FAKE_RW           0x238
28237         do_facet ost1 $LCTL set_param fail_loc=0x238
28238
28239         local start_time=$(date +%s.%N)
28240         $dd_cmd bs=1M count=$blocks oflag=sync ||
28241                 error "fake dd $read_write error"
28242         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28243
28244         if [ "$read_write" = "write" ]; then
28245                 # verify file size
28246                 cancel_lru_locks osc
28247                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28248                         error "$tfile size not $blocks MB"
28249         fi
28250         do_facet ost1 $LCTL set_param fail_loc=0
28251
28252         echo "fake $read_write $duration_fake vs. normal $read_write" \
28253                 "$duration in seconds"
28254         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28255                 error_not_in_vm "fake write is slower"
28256
28257         $LCTL set_param -n debug="$saved_debug"
28258         rm -f $DIR/$tfile
28259 }
28260 test_399a() { # LU-7655 for OST fake write
28261         remote_ost_nodsh && skip "remote OST with nodsh"
28262
28263         test_fake_rw write
28264 }
28265 run_test 399a "fake write should not be slower than normal write"
28266
28267 test_399b() { # LU-8726 for OST fake read
28268         remote_ost_nodsh && skip "remote OST with nodsh"
28269         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28270                 skip_env "ldiskfs only test"
28271         fi
28272
28273         test_fake_rw read
28274 }
28275 run_test 399b "fake read should not be slower than normal read"
28276
28277 test_400a() { # LU-1606, was conf-sanity test_74
28278         if ! which $CC > /dev/null 2>&1; then
28279                 skip_env "$CC is not installed"
28280         fi
28281
28282         local extra_flags=''
28283         local out=$TMP/$tfile
28284         local prefix=/usr/include/lustre
28285         local prog
28286
28287         # Oleg removes .c files in his test rig so test if any c files exist
28288         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28289                 skip_env "Needed .c test files are missing"
28290
28291         if ! [[ -d $prefix ]]; then
28292                 # Assume we're running in tree and fixup the include path.
28293                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28294                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28295                 extra_flags+=" -L$LUSTRE/utils/.libs"
28296         fi
28297
28298         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28299                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28300                         error "client api broken"
28301         done
28302         rm -f $out
28303 }
28304 run_test 400a "Lustre client api program can compile and link"
28305
28306 test_400b() { # LU-1606, LU-5011
28307         local header
28308         local out=$TMP/$tfile
28309         local prefix=/usr/include/linux/lustre
28310
28311         # We use a hard coded prefix so that this test will not fail
28312         # when run in tree. There are headers in lustre/include/lustre/
28313         # that are not packaged (like lustre_idl.h) and have more
28314         # complicated include dependencies (like config.h and lnet/types.h).
28315         # Since this test about correct packaging we just skip them when
28316         # they don't exist (see below) rather than try to fixup cppflags.
28317
28318         if ! which $CC > /dev/null 2>&1; then
28319                 skip_env "$CC is not installed"
28320         fi
28321
28322         for header in $prefix/*.h; do
28323                 if ! [[ -f "$header" ]]; then
28324                         continue
28325                 fi
28326
28327                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28328                         continue # lustre_ioctl.h is internal header
28329                 fi
28330
28331                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28332                         error "cannot compile '$header'"
28333         done
28334         rm -f $out
28335 }
28336 run_test 400b "packaged headers can be compiled"
28337
28338 test_401a() { #LU-7437
28339         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28340         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28341
28342         #count the number of parameters by "list_param -R"
28343         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28344         #count the number of parameters by listing proc files
28345         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28346         echo "proc_dirs='$proc_dirs'"
28347         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28348         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28349                       sort -u | wc -l)
28350
28351         [ $params -eq $procs ] ||
28352                 error "found $params parameters vs. $procs proc files"
28353
28354         # test the list_param -D option only returns directories
28355         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28356         #count the number of parameters by listing proc directories
28357         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28358                 sort -u | wc -l)
28359
28360         [ $params -eq $procs ] ||
28361                 error "found $params parameters vs. $procs proc files"
28362 }
28363 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28364
28365 test_401b() {
28366         # jobid_var may not allow arbitrary values, so use jobid_name
28367         # if available
28368         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28369                 local testname=jobid_name tmp='testing%p'
28370         else
28371                 local testname=jobid_var tmp=testing
28372         fi
28373
28374         local save=$($LCTL get_param -n $testname)
28375
28376         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28377                 error "no error returned when setting bad parameters"
28378
28379         local jobid_new=$($LCTL get_param -n foe $testname baz)
28380         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28381
28382         $LCTL set_param -n fog=bam $testname=$save bat=fog
28383         local jobid_old=$($LCTL get_param -n foe $testname bag)
28384         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28385 }
28386 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28387
28388 test_401c() {
28389         # jobid_var may not allow arbitrary values, so use jobid_name
28390         # if available
28391         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28392                 local testname=jobid_name
28393         else
28394                 local testname=jobid_var
28395         fi
28396
28397         local jobid_var_old=$($LCTL get_param -n $testname)
28398         local jobid_var_new
28399
28400         $LCTL set_param $testname= &&
28401                 error "no error returned for 'set_param a='"
28402
28403         jobid_var_new=$($LCTL get_param -n $testname)
28404         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28405                 error "$testname was changed by setting without value"
28406
28407         $LCTL set_param $testname &&
28408                 error "no error returned for 'set_param a'"
28409
28410         jobid_var_new=$($LCTL get_param -n $testname)
28411         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28412                 error "$testname was changed by setting without value"
28413 }
28414 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28415
28416 test_401d() {
28417         # jobid_var may not allow arbitrary values, so use jobid_name
28418         # if available
28419         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28420                 local testname=jobid_name new_value='foo=bar%p'
28421         else
28422                 local testname=jobid_var new_valuie=foo=bar
28423         fi
28424
28425         local jobid_var_old=$($LCTL get_param -n $testname)
28426         local jobid_var_new
28427
28428         $LCTL set_param $testname=$new_value ||
28429                 error "'set_param a=b' did not accept a value containing '='"
28430
28431         jobid_var_new=$($LCTL get_param -n $testname)
28432         [[ "$jobid_var_new" == "$new_value" ]] ||
28433                 error "'set_param a=b' failed on a value containing '='"
28434
28435         # Reset the $testname to test the other format
28436         $LCTL set_param $testname=$jobid_var_old
28437         jobid_var_new=$($LCTL get_param -n $testname)
28438         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28439                 error "failed to reset $testname"
28440
28441         $LCTL set_param $testname $new_value ||
28442                 error "'set_param a b' did not accept a value containing '='"
28443
28444         jobid_var_new=$($LCTL get_param -n $testname)
28445         [[ "$jobid_var_new" == "$new_value" ]] ||
28446                 error "'set_param a b' failed on a value containing '='"
28447
28448         $LCTL set_param $testname $jobid_var_old
28449         jobid_var_new=$($LCTL get_param -n $testname)
28450         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28451                 error "failed to reset $testname"
28452 }
28453 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28454
28455 test_401e() { # LU-14779
28456         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28457                 error "lctl list_param MGC* failed"
28458         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28459         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28460                 error "lctl get_param lru_size failed"
28461 }
28462 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28463
28464 test_402() {
28465         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28466         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28467                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28468         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28469                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28470                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28471         remote_mds_nodsh && skip "remote MDS with nodsh"
28472
28473         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28474 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28475         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28476         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28477                 echo "Touch failed - OK"
28478 }
28479 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28480
28481 test_403() {
28482         local file1=$DIR/$tfile.1
28483         local file2=$DIR/$tfile.2
28484         local tfile=$TMP/$tfile
28485
28486         rm -f $file1 $file2 $tfile
28487
28488         touch $file1
28489         ln $file1 $file2
28490
28491         # 30 sec OBD_TIMEOUT in ll_getattr()
28492         # right before populating st_nlink
28493         $LCTL set_param fail_loc=0x80001409
28494         stat -c %h $file1 > $tfile &
28495
28496         # create an alias, drop all locks and reclaim the dentry
28497         < $file2
28498         cancel_lru_locks mdc
28499         cancel_lru_locks osc
28500         sysctl -w vm.drop_caches=2
28501
28502         wait
28503
28504         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28505
28506         rm -f $tfile $file1 $file2
28507 }
28508 run_test 403 "i_nlink should not drop to zero due to aliasing"
28509
28510 test_404() { # LU-6601
28511         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28512                 skip "Need server version newer than 2.8.52"
28513         remote_mds_nodsh && skip "remote MDS with nodsh"
28514
28515         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28516                 awk '/osp .*-osc-MDT/ { print $4}')
28517
28518         local osp
28519         for osp in $mosps; do
28520                 echo "Deactivate: " $osp
28521                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28522                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28523                         awk -vp=$osp '$4 == p { print $2 }')
28524                 [ $stat = IN ] || {
28525                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28526                         error "deactivate error"
28527                 }
28528                 echo "Activate: " $osp
28529                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28530                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28531                         awk -vp=$osp '$4 == p { print $2 }')
28532                 [ $stat = UP ] || {
28533                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28534                         error "activate error"
28535                 }
28536         done
28537 }
28538 run_test 404 "validate manual {de}activated works properly for OSPs"
28539
28540 test_405() {
28541         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28542         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28543                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28544                         skip "Layout swap lock is not supported"
28545
28546         check_swap_layouts_support
28547         check_swap_layout_no_dom $DIR
28548
28549         test_mkdir $DIR/$tdir
28550         swap_lock_test -d $DIR/$tdir ||
28551                 error "One layout swap locked test failed"
28552 }
28553 run_test 405 "Various layout swap lock tests"
28554
28555 test_406() {
28556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28560         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28561                 skip "Need MDS version at least 2.8.50"
28562
28563         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28564         local test_pool=$TESTNAME
28565
28566         pool_add $test_pool || error "pool_add failed"
28567         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28568                 error "pool_add_targets failed"
28569
28570         save_layout_restore_at_exit $MOUNT
28571
28572         # parent set default stripe count only, child will stripe from both
28573         # parent and fs default
28574         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28575                 error "setstripe $MOUNT failed"
28576         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28577         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28578         for i in $(seq 10); do
28579                 local f=$DIR/$tdir/$tfile.$i
28580                 touch $f || error "touch failed"
28581                 local count=$($LFS getstripe -c $f)
28582                 [ $count -eq $OSTCOUNT ] ||
28583                         error "$f stripe count $count != $OSTCOUNT"
28584                 local offset=$($LFS getstripe -i $f)
28585                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28586                 local size=$($LFS getstripe -S $f)
28587                 [ $size -eq $((def_stripe_size * 2)) ] ||
28588                         error "$f stripe size $size != $((def_stripe_size * 2))"
28589                 local pool=$($LFS getstripe -p $f)
28590                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28591         done
28592
28593         # change fs default striping, delete parent default striping, now child
28594         # will stripe from new fs default striping only
28595         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28596                 error "change $MOUNT default stripe failed"
28597         $LFS setstripe -c 0 $DIR/$tdir ||
28598                 error "delete $tdir default stripe failed"
28599         for i in $(seq 11 20); do
28600                 local f=$DIR/$tdir/$tfile.$i
28601                 touch $f || error "touch $f failed"
28602                 local count=$($LFS getstripe -c $f)
28603                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28604                 local offset=$($LFS getstripe -i $f)
28605                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28606                 local size=$($LFS getstripe -S $f)
28607                 [ $size -eq $def_stripe_size ] ||
28608                         error "$f stripe size $size != $def_stripe_size"
28609                 local pool=$($LFS getstripe -p $f)
28610                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28611         done
28612
28613         unlinkmany $DIR/$tdir/$tfile. 1 20
28614
28615         local f=$DIR/$tdir/$tfile
28616         pool_remove_all_targets $test_pool $f
28617         pool_remove $test_pool $f
28618 }
28619 run_test 406 "DNE support fs default striping"
28620
28621 test_407() {
28622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28623         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28624                 skip "Need MDS version at least 2.8.55"
28625         remote_mds_nodsh && skip "remote MDS with nodsh"
28626
28627         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28628                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28629         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28630                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28631         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28632
28633         #define OBD_FAIL_DT_TXN_STOP    0x2019
28634         for idx in $(seq $MDSCOUNT); do
28635                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28636         done
28637         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28638         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28639                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28640         true
28641 }
28642 run_test 407 "transaction fail should cause operation fail"
28643
28644 test_408() {
28645         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28646
28647         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28648         lctl set_param fail_loc=0x8000040a
28649         # let ll_prepare_partial_page() fail
28650         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28651
28652         rm -f $DIR/$tfile
28653
28654         # create at least 100 unused inodes so that
28655         # shrink_icache_memory(0) should not return 0
28656         touch $DIR/$tfile-{0..100}
28657         rm -f $DIR/$tfile-{0..100}
28658         sync
28659
28660         echo 2 > /proc/sys/vm/drop_caches
28661 }
28662 run_test 408 "drop_caches should not hang due to page leaks"
28663
28664 test_409()
28665 {
28666         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28667
28668         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28669         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28670         touch $DIR/$tdir/guard || error "(2) Fail to create"
28671
28672         local PREFIX=$(str_repeat 'A' 128)
28673         echo "Create 1K hard links start at $(date)"
28674         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28675                 error "(3) Fail to hard link"
28676
28677         echo "Links count should be right although linkEA overflow"
28678         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28679         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28680         [ $linkcount -eq 1001 ] ||
28681                 error "(5) Unexpected hard links count: $linkcount"
28682
28683         echo "List all links start at $(date)"
28684         ls -l $DIR/$tdir/foo > /dev/null ||
28685                 error "(6) Fail to list $DIR/$tdir/foo"
28686
28687         echo "Unlink hard links start at $(date)"
28688         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28689                 error "(7) Fail to unlink"
28690         echo "Unlink hard links finished at $(date)"
28691 }
28692 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28693
28694 test_410()
28695 {
28696         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28697                 skip "Need client version at least 2.9.59"
28698
28699         # Create a file, and stat it from the kernel
28700         local testfile=$DIR/$tfile
28701         touch $testfile
28702
28703         local run_id=$RANDOM
28704         local my_ino=$(stat --format "%i" $testfile)
28705
28706         # Try to insert the module.
28707         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28708                 error "load_module failed"
28709
28710         # Anything but success is a test failure
28711         dmesg | grep -q \
28712             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28713             error "no inode match"
28714
28715         # Remove the test module
28716         rmmod -v kinode ||
28717                 error "rmmod failed (may trigger a failure in a later test)"
28718 }
28719 run_test 410 "Test inode number returned from kernel thread"
28720
28721 cleanup_test411_cgroup() {
28722         trap 0
28723         cat $1/memory.stat
28724         rmdir "$1"
28725 }
28726
28727 test_411a() {
28728         local cg_basedir=/sys/fs/cgroup/memory
28729         # LU-9966
28730         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28731                 skip "no setup for cgroup"
28732
28733         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28734                 error "test file creation failed"
28735         cancel_lru_locks osc
28736
28737         # Create a very small memory cgroup to force a slab allocation error
28738         local cgdir=$cg_basedir/osc_slab_alloc
28739         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28740         trap "cleanup_test411_cgroup $cgdir" EXIT
28741         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28742         echo 1M > $cgdir/memory.limit_in_bytes
28743
28744         # Should not LBUG, just be killed by oom-killer
28745         # dd will return 0 even allocation failure in some environment.
28746         # So don't check return value
28747         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28748         cleanup_test411_cgroup $cgdir
28749
28750         return 0
28751 }
28752 run_test 411a "Slab allocation error with cgroup does not LBUG"
28753
28754 test_411b() {
28755         local cg_basedir=/sys/fs/cgroup/memory
28756         # LU-9966
28757         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28758                 skip "no setup for cgroup"
28759         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28760         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28761         # limit, so we have 384M in cgroup
28762         # (arm) this seems to hit OOM more often than x86, so 1024M
28763         if [[ $(uname -m) = aarch64 ]]; then
28764                 local memlimit_mb=1024
28765         else
28766                 local memlimit_mb=384
28767         fi
28768
28769         # Create a cgroup and set memory limit
28770         # (tfile is used as an easy way to get a recognizable cgroup name)
28771         local cgdir=$cg_basedir/$tfile
28772         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28773         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28774         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28775
28776         echo "writing first file"
28777         # Write a file 4x the memory limit in size
28778         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28779                 error "(1) failed to write successfully"
28780
28781         sync
28782         cancel_lru_locks osc
28783
28784         rm -f $DIR/$tfile
28785         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28786
28787         # Try writing at a larger block size
28788         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28789         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28790         # need *some* memory to do IO in)
28791         echo "writing at larger block size"
28792         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28793                 error "(3) failed to write successfully"
28794
28795         sync
28796         cancel_lru_locks osc
28797         rm -f $DIR/$tfile
28798         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28799
28800         # Try writing multiple files at once
28801         echo "writing multiple files"
28802         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28803         local pid1=$!
28804         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28805         local pid2=$!
28806         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28807         local pid3=$!
28808         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28809         local pid4=$!
28810
28811         wait $pid1
28812         local rc1=$?
28813         wait $pid2
28814         local rc2=$?
28815         wait $pid3
28816         local rc3=$?
28817         wait $pid4
28818         local rc4=$?
28819         if (( rc1 != 0)); then
28820                 error "error $rc1 writing to file from $pid1"
28821         fi
28822         if (( rc2 != 0)); then
28823                 error "error $rc2 writing to file from $pid2"
28824         fi
28825         if (( rc3 != 0)); then
28826                 error "error $rc3 writing to file from $pid3"
28827         fi
28828         if (( rc4 != 0)); then
28829                 error "error $rc4 writing to file from $pid4"
28830         fi
28831
28832         sync
28833         cancel_lru_locks osc
28834
28835         # These files can be large-ish (~1 GiB total), so delete them rather
28836         # than leave for later cleanup
28837         rm -f $DIR/$tfile.*
28838         return 0
28839 }
28840 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28841
28842 test_412() {
28843         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28844         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28845                 skip "Need server version at least 2.10.55"
28846
28847         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28848                 error "mkdir failed"
28849         $LFS getdirstripe $DIR/$tdir
28850         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28851         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28852                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28853         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28854         [ $stripe_count -eq 2 ] ||
28855                 error "expect 2 get $stripe_count"
28856
28857         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28858
28859         local index
28860         local index2
28861
28862         # subdirs should be on the same MDT as parent
28863         for i in $(seq 0 $((MDSCOUNT - 1))); do
28864                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28865                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28866                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28867                 (( index == i )) || error "mdt$i/sub on MDT$index"
28868         done
28869
28870         # stripe offset -1, ditto
28871         for i in {1..10}; do
28872                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28873                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28874                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28875                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28876                 (( index == index2 )) ||
28877                         error "qos$i on MDT$index, sub on MDT$index2"
28878         done
28879
28880         local testdir=$DIR/$tdir/inherit
28881
28882         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28883         # inherit 2 levels
28884         for i in 1 2; do
28885                 testdir=$testdir/s$i
28886                 mkdir $testdir || error "mkdir $testdir failed"
28887                 index=$($LFS getstripe -m $testdir)
28888                 (( index == 1 )) ||
28889                         error "$testdir on MDT$index"
28890         done
28891
28892         # not inherit any more
28893         testdir=$testdir/s3
28894         mkdir $testdir || error "mkdir $testdir failed"
28895         getfattr -d -m dmv $testdir | grep dmv &&
28896                 error "default LMV set on $testdir" || true
28897 }
28898 run_test 412 "mkdir on specific MDTs"
28899
28900 TEST413_COUNT=${TEST413_COUNT:-200}
28901
28902 #
28903 # set_maxage() is used by test_413 only.
28904 # This is a helper function to set maxage. Does not return any value.
28905 # Input: maxage to set
28906 #
28907 set_maxage() {
28908         local lmv_qos_maxage
28909         local lod_qos_maxage
28910         local new_maxage=$1
28911
28912         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28913         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28914         stack_trap "$LCTL set_param \
28915                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28916         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28917                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28918         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28919                 lod.*.mdt_qos_maxage=$new_maxage
28920         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28921                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28922 }
28923
28924 generate_uneven_mdts() {
28925         local threshold=$1
28926         local ffree
28927         local bavail
28928         local max
28929         local min
28930         local max_index
28931         local min_index
28932         local tmp
28933         local i
28934
28935         echo
28936         echo "Check for uneven MDTs: "
28937
28938         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28939         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28940         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28941
28942         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28943         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28944         max_index=0
28945         min_index=0
28946         for ((i = 1; i < ${#ffree[@]}; i++)); do
28947                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28948                 if [ $tmp -gt $max ]; then
28949                         max=$tmp
28950                         max_index=$i
28951                 fi
28952                 if [ $tmp -lt $min ]; then
28953                         min=$tmp
28954                         min_index=$i
28955                 fi
28956         done
28957
28958         (( min > 0 )) || skip "low space on MDT$min_index"
28959         (( ${ffree[min_index]} > 0 )) ||
28960                 skip "no free files on MDT$min_index"
28961         (( ${ffree[min_index]} < 10000000 )) ||
28962                 skip "too many free files on MDT$min_index"
28963
28964         # Check if we need to generate uneven MDTs
28965         local diff=$(((max - min) * 100 / min))
28966         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28967         local testdir # individual folder within $testdirp
28968         local start
28969         local cmd
28970
28971         # fallocate is faster to consume space on MDT, if available
28972         if check_fallocate_supported mds$((min_index + 1)); then
28973                 cmd="fallocate -l 128K "
28974         else
28975                 cmd="dd if=/dev/zero bs=128K count=1 of="
28976         fi
28977
28978         echo "using cmd $cmd"
28979         for (( i = 0; diff < threshold; i++ )); do
28980                 testdir=${testdirp}/$i
28981                 [ -d $testdir ] && continue
28982
28983                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28984
28985                 mkdir -p $testdirp
28986                 # generate uneven MDTs, create till $threshold% diff
28987                 echo -n "weight diff=$diff% must be > $threshold% ..."
28988                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28989                 $LFS mkdir -i $min_index $testdir ||
28990                         error "mkdir $testdir failed"
28991                 $LFS setstripe -E 1M -L mdt $testdir ||
28992                         error "setstripe $testdir failed"
28993                 start=$SECONDS
28994                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28995                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28996                 done
28997                 sync; sleep 1; sync
28998
28999                 # wait for QOS to update
29000                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
29001
29002                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
29003                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
29004                 max=$(((${ffree[max_index]} >> 8) *
29005                         (${bavail[max_index]} * bsize >> 16)))
29006                 min=$(((${ffree[min_index]} >> 8) *
29007                         (${bavail[min_index]} * bsize >> 16)))
29008                 (( min > 0 )) || skip "low space on MDT$min_index"
29009                 diff=$(((max - min) * 100 / min))
29010         done
29011
29012         echo "MDT filesfree available: ${ffree[*]}"
29013         echo "MDT blocks available: ${bavail[*]}"
29014         echo "weight diff=$diff%"
29015 }
29016
29017 test_qos_mkdir() {
29018         local mkdir_cmd=$1
29019         local stripe_count=$2
29020         local mdts=$(comma_list $(mdts_nodes))
29021
29022         local testdir
29023         local lmv_qos_prio_free
29024         local lmv_qos_threshold_rr
29025         local lod_qos_prio_free
29026         local lod_qos_threshold_rr
29027         local total
29028         local count
29029         local i
29030
29031         # @total is total directories created if it's testing plain
29032         # directories, otherwise it's total stripe object count for
29033         # striped directories test.
29034         # remote/striped directory unlinking is slow on zfs and may
29035         # timeout, test with fewer directories
29036         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
29037
29038         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
29039         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
29040         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29041                 head -n1)
29042         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
29043         stack_trap "$LCTL set_param \
29044                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
29045         stack_trap "$LCTL set_param \
29046                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
29047
29048         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
29049                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
29050         lod_qos_prio_free=${lod_qos_prio_free%%%}
29051         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
29052                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
29053         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
29054         stack_trap "do_nodes $mdts $LCTL set_param \
29055                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
29056         stack_trap "do_nodes $mdts $LCTL set_param \
29057                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
29058
29059         # decrease statfs age, so that it can be updated in time
29060         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
29061         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
29062
29063         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29064         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
29065
29066         testdir=$DIR/$tdir-s$stripe_count/rr
29067
29068         local stripe_index=$($LFS getstripe -m $testdir)
29069         local test_mkdir_rr=true
29070
29071         getfattr -d -m dmv -e hex $testdir | grep dmv
29072         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
29073                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
29074                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
29075                         test_mkdir_rr=false
29076         fi
29077
29078         echo
29079         $test_mkdir_rr &&
29080                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
29081                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
29082
29083         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29084         for (( i = 0; i < total / stripe_count; i++ )); do
29085                 eval $mkdir_cmd $testdir/subdir$i ||
29086                         error "$mkdir_cmd subdir$i failed"
29087         done
29088
29089         for (( i = 0; i < $MDSCOUNT; i++ )); do
29090                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29091                 echo "$count directories created on MDT$i"
29092                 if $test_mkdir_rr; then
29093                         (( count == total / stripe_count / MDSCOUNT )) ||
29094                                 error "subdirs are not evenly distributed"
29095                 elif (( i == stripe_index )); then
29096                         (( count == total / stripe_count )) ||
29097                                 error "$count subdirs created on MDT$i"
29098                 else
29099                         (( count == 0 )) ||
29100                                 error "$count subdirs created on MDT$i"
29101                 fi
29102
29103                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
29104                         count=$($LFS getdirstripe $testdir/* |
29105                                 grep -c -P "^\s+$i\t")
29106                         echo "$count stripes created on MDT$i"
29107                         # deviation should < 5% of average
29108                         delta=$((count - total / MDSCOUNT))
29109                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
29110                                 error "stripes are not evenly distributed"
29111                 fi
29112         done
29113
29114         echo
29115         echo "Check for uneven MDTs: "
29116
29117         local ffree
29118         local bavail
29119         local max
29120         local min
29121         local max_index
29122         local min_index
29123         local tmp
29124
29125         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29126         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29127         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29128
29129         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29130         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29131         max_index=0
29132         min_index=0
29133         for ((i = 1; i < ${#ffree[@]}; i++)); do
29134                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29135                 if [ $tmp -gt $max ]; then
29136                         max=$tmp
29137                         max_index=$i
29138                 fi
29139                 if [ $tmp -lt $min ]; then
29140                         min=$tmp
29141                         min_index=$i
29142                 fi
29143         done
29144         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29145
29146         (( min > 0 )) || skip "low space on MDT$min_index"
29147         (( ${ffree[min_index]} < 10000000 )) ||
29148                 skip "too many free files on MDT$min_index"
29149
29150         generate_uneven_mdts 120
29151
29152         echo "MDT filesfree available: ${ffree[*]}"
29153         echo "MDT blocks available: ${bavail[*]}"
29154         echo "weight diff=$(((max - min) * 100 / min))%"
29155         echo
29156         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29157
29158         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29159         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29160         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29161         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29162
29163         sleep 1
29164
29165         testdir=$DIR/$tdir-s$stripe_count/qos
29166
29167         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29168         for (( i = 0; i < total / stripe_count; i++ )); do
29169                 eval $mkdir_cmd $testdir/subdir$i ||
29170                         error "$mkdir_cmd subdir$i failed"
29171         done
29172
29173         max=0
29174         for (( i = 0; i < $MDSCOUNT; i++ )); do
29175                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29176                 (( count > max )) && max=$count
29177                 echo "$count directories created on MDT$i : curmax=$max"
29178         done
29179
29180         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29181
29182         # D-value should > 10% of average
29183         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29184                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29185
29186         # ditto for stripes
29187         if (( stripe_count > 1 )); then
29188                 max=0
29189                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29190                         count=$($LFS getdirstripe $testdir/* |
29191                                 grep -c -P "^\s+$i\t")
29192                         (( count > max )) && max=$count
29193                         echo "$count stripes created on MDT$i"
29194                 done
29195
29196                 min=$($LFS getdirstripe $testdir/* |
29197                         grep -c -P "^\s+$min_index\t")
29198                 (( max - min > total / MDSCOUNT / 10 )) ||
29199                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29200         fi
29201 }
29202
29203 most_full_mdt() {
29204         local ffree
29205         local bavail
29206         local bsize
29207         local min
29208         local min_index
29209         local tmp
29210
29211         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29212         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29213         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29214
29215         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29216         min_index=0
29217         for ((i = 1; i < ${#ffree[@]}; i++)); do
29218                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29219                 (( tmp < min )) && min=$tmp && min_index=$i
29220         done
29221
29222         echo -n $min_index
29223 }
29224
29225 test_413a() {
29226         [ $MDSCOUNT -lt 2 ] &&
29227                 skip "We need at least 2 MDTs for this test"
29228
29229         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29230                 skip "Need server version at least 2.12.52"
29231
29232         local stripe_max=$((MDSCOUNT - 1))
29233         local stripe_count
29234
29235         # let caller set maxage for latest result
29236         set_maxage 1
29237
29238         # fill MDT unevenly
29239         generate_uneven_mdts 120
29240
29241         # test 4-stripe directory at most, otherwise it's too slow
29242         # We are being very defensive. Although Autotest uses 4 MDTs.
29243         # We make sure stripe_max does not go over 4.
29244         (( stripe_max > 4 )) && stripe_max=4
29245         # unlinking striped directory is slow on zfs, and may timeout, only test
29246         # plain directory
29247         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29248         for stripe_count in $(seq 1 $stripe_max); do
29249                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29250                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29251                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29252                         error "mkdir failed"
29253                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29254         done
29255 }
29256 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29257
29258 test_413b() {
29259         [ $MDSCOUNT -lt 2 ] &&
29260                 skip "We need at least 2 MDTs for this test"
29261
29262         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29263                 skip "Need server version at least 2.12.52"
29264
29265         local stripe_max=$((MDSCOUNT - 1))
29266         local testdir
29267         local stripe_count
29268
29269         # let caller set maxage for latest result
29270         set_maxage 1
29271
29272         # fill MDT unevenly
29273         generate_uneven_mdts 120
29274
29275         # test 4-stripe directory at most, otherwise it's too slow
29276         # We are being very defensive. Although Autotest uses 4 MDTs.
29277         # We make sure stripe_max does not go over 4.
29278         (( stripe_max > 4 )) && stripe_max=4
29279         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29280         for stripe_count in $(seq 1 $stripe_max); do
29281                 testdir=$DIR/$tdir-s$stripe_count
29282                 mkdir $testdir || error "mkdir $testdir failed"
29283                 mkdir $testdir/rr || error "mkdir rr failed"
29284                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29285                         error "mkdir qos failed"
29286                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29287                         $testdir/rr || error "setdirstripe rr failed"
29288                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29289                         error "setdirstripe failed"
29290                 test_qos_mkdir "mkdir" $stripe_count
29291         done
29292 }
29293 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29294
29295 test_413c() {
29296         (( $MDSCOUNT >= 2 )) ||
29297                 skip "We need at least 2 MDTs for this test"
29298
29299         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29300                 skip "Need server version at least 2.14.51"
29301
29302         local testdir
29303         local inherit
29304         local inherit_rr
29305         local lmv_qos_maxage
29306         local lod_qos_maxage
29307
29308         # let caller set maxage for latest result
29309         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29310         $LCTL set_param lmv.*.qos_maxage=1
29311         stack_trap "$LCTL set_param \
29312                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29313         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29314                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29315         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29316                 lod.*.mdt_qos_maxage=1
29317         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29318                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29319
29320         # fill MDT unevenly
29321         generate_uneven_mdts 120
29322
29323         testdir=$DIR/${tdir}-s1
29324         mkdir $testdir || error "mkdir $testdir failed"
29325         mkdir $testdir/rr || error "mkdir rr failed"
29326         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29327         # default max_inherit is -1, default max_inherit_rr is 0
29328         $LFS setdirstripe -D -c 1 $testdir/rr ||
29329                 error "setdirstripe rr failed"
29330         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29331                 error "setdirstripe qos failed"
29332         test_qos_mkdir "mkdir" 1
29333
29334         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29335         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29336         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29337         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29338         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29339
29340         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29341         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29342         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29343         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29344         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29345         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29346         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29347                 error "level2 shouldn't have default LMV" || true
29348 }
29349 run_test 413c "mkdir with default LMV max inherit rr"
29350
29351 test_413d() {
29352         (( MDSCOUNT >= 2 )) ||
29353                 skip "We need at least 2 MDTs for this test"
29354
29355         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29356                 skip "Need server version at least 2.14.51"
29357
29358         local lmv_qos_threshold_rr
29359
29360         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29361                 head -n1)
29362         stack_trap "$LCTL set_param \
29363                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29364
29365         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29366         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29367         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29368                 error "$tdir shouldn't have default LMV"
29369         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29370                 error "mkdir sub failed"
29371
29372         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29373
29374         (( count == 100 )) || error "$count subdirs on MDT0"
29375 }
29376 run_test 413d "inherit ROOT default LMV"
29377
29378 test_413e() {
29379         (( MDSCOUNT >= 2 )) ||
29380                 skip "We need at least 2 MDTs for this test"
29381         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29382                 skip "Need server version at least 2.14.55"
29383
29384         local testdir=$DIR/$tdir
29385         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29386         local max_inherit
29387         local sub_max_inherit
29388
29389         mkdir -p $testdir || error "failed to create $testdir"
29390
29391         # set default max-inherit to -1 if stripe count is 0 or 1
29392         $LFS setdirstripe -D -c 1 $testdir ||
29393                 error "failed to set default LMV"
29394         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29395         (( max_inherit == -1 )) ||
29396                 error "wrong max_inherit value $max_inherit"
29397
29398         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29399         $LFS setdirstripe -D -c -1 $testdir ||
29400                 error "failed to set default LMV"
29401         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29402         (( max_inherit > 0 )) ||
29403                 error "wrong max_inherit value $max_inherit"
29404
29405         # and the subdir will decrease the max_inherit by 1
29406         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29407         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29408         (( sub_max_inherit == max_inherit - 1)) ||
29409                 error "wrong max-inherit of subdir $sub_max_inherit"
29410
29411         # check specified --max-inherit and warning message
29412         stack_trap "rm -f $tmpfile"
29413         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29414                 error "failed to set default LMV"
29415         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29416         (( max_inherit == -1 )) ||
29417                 error "wrong max_inherit value $max_inherit"
29418
29419         # check the warning messages
29420         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29421                 error "failed to detect warning string"
29422         fi
29423 }
29424 run_test 413e "check default max-inherit value"
29425
29426 test_fs_dmv_inherit()
29427 {
29428         local testdir=$DIR/$tdir
29429
29430         local count
29431         local inherit
29432         local inherit_rr
29433
29434         for i in 1 2; do
29435                 mkdir $testdir || error "mkdir $testdir failed"
29436                 count=$($LFS getdirstripe -D -c $testdir)
29437                 (( count == 1 )) ||
29438                         error "$testdir default LMV count mismatch $count != 1"
29439                 inherit=$($LFS getdirstripe -D -X $testdir)
29440                 (( inherit == 3 - i )) ||
29441                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29442                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29443                 (( inherit_rr == 3 - i )) ||
29444                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29445                 testdir=$testdir/sub
29446         done
29447
29448         mkdir $testdir || error "mkdir $testdir failed"
29449         count=$($LFS getdirstripe -D -c $testdir)
29450         (( count == 0 )) ||
29451                 error "$testdir default LMV count not zero: $count"
29452 }
29453
29454 test_413f() {
29455         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29456
29457         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29458                 skip "Need server version at least 2.14.55"
29459
29460         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29461                 error "dump $DIR default LMV failed"
29462         stack_trap "setfattr --restore=$TMP/dmv.ea"
29463
29464         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29465                 error "set $DIR default LMV failed"
29466
29467         test_fs_dmv_inherit
29468 }
29469 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29470
29471 test_413g() {
29472         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29473
29474         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29475         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29476                 error "dump $DIR default LMV failed"
29477         stack_trap "setfattr --restore=$TMP/dmv.ea"
29478
29479         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29480                 error "set $DIR default LMV failed"
29481
29482         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29483                 error "mount $MOUNT2 failed"
29484         stack_trap "umount_client $MOUNT2"
29485
29486         local saved_DIR=$DIR
29487
29488         export DIR=$MOUNT2
29489
29490         stack_trap "export DIR=$saved_DIR"
29491
29492         # first check filesystem-wide default LMV inheritance
29493         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29494
29495         # then check subdirs are spread to all MDTs
29496         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29497
29498         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29499
29500         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29501 }
29502 run_test 413g "enforce ROOT default LMV on subdir mount"
29503
29504 test_413h() {
29505         (( MDSCOUNT >= 2 )) ||
29506                 skip "We need at least 2 MDTs for this test"
29507
29508         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29509                 skip "Need server version at least 2.15.50.6"
29510
29511         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29512
29513         stack_trap "$LCTL set_param \
29514                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29515         $LCTL set_param lmv.*.qos_maxage=1
29516
29517         local depth=5
29518         local rr_depth=4
29519         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29520         local count=$((MDSCOUNT * 20))
29521
29522         generate_uneven_mdts 50
29523
29524         mkdir -p $dir || error "mkdir $dir failed"
29525         stack_trap "rm -rf $dir"
29526         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29527                 --max-inherit-rr=$rr_depth $dir
29528
29529         for ((d=0; d < depth + 2; d++)); do
29530                 log "dir=$dir:"
29531                 for ((sub=0; sub < count; sub++)); do
29532                         mkdir $dir/d$sub
29533                 done
29534                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29535                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29536                 # subdirs within $rr_depth should be created round-robin
29537                 if (( d < rr_depth )); then
29538                         (( ${num[0]} != count )) ||
29539                                 error "all objects created on MDT ${num[1]}"
29540                 fi
29541
29542                 dir=$dir/d0
29543         done
29544 }
29545 run_test 413h "don't stick to parent for round-robin dirs"
29546
29547 test_413i() {
29548         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29549
29550         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29551                 skip "Need server version at least 2.14.55"
29552
29553         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29554                 error "dump $DIR default LMV failed"
29555         stack_trap "setfattr --restore=$TMP/dmv.ea"
29556
29557         local testdir=$DIR/$tdir
29558         local def_max_rr=1
29559         local def_max=3
29560         local count
29561
29562         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29563                 --max-inherit-rr=$def_max_rr $DIR ||
29564                 error "set $DIR default LMV failed"
29565
29566         for i in $(seq 2 3); do
29567                 def_max=$((def_max - 1))
29568                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29569
29570                 mkdir $testdir
29571                 # RR is decremented and keeps zeroed once exhausted
29572                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29573                 (( count == def_max_rr )) ||
29574                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29575
29576                 # max-inherit is decremented
29577                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29578                 (( count == def_max )) ||
29579                         error_noexit "$testdir: max-inherit $count != $def_max"
29580
29581                 testdir=$testdir/d$i
29582         done
29583
29584         # d3 is the last inherited from ROOT, no inheritance anymore
29585         # i.e. no the default layout anymore
29586         mkdir -p $testdir/d4/d5
29587         count=$($LFS getdirstripe -D --max-inherit $testdir)
29588         (( count == -1 )) ||
29589                 error_noexit "$testdir: max-inherit $count != -1"
29590
29591         local p_count=$($LFS getdirstripe -i $testdir)
29592
29593         for i in $(seq 4 5); do
29594                 testdir=$testdir/d$i
29595
29596                 # the root default layout is not applied once exhausted
29597                 count=$($LFS getdirstripe -i $testdir)
29598                 (( count == p_count )) ||
29599                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29600         done
29601
29602         $LFS setdirstripe -i 0 $DIR/d2
29603         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29604         (( count == -1 )) ||
29605                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29606 }
29607 run_test 413i "check default layout inheritance"
29608
29609 test_413j()
29610 {
29611         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29612
29613         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29614         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29615                 error "setdirstripe $tdir failed"
29616
29617         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29618                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29619
29620         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29621         # setfattr dmv calls setdirstripe -D
29622         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29623                 error "setfattr sub failed"
29624         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29625                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29626
29627         [ $value == $value2 ] || error "dmv mismatch"
29628
29629         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29630
29631         # do not allow remove dmv by setfattr -x
29632         do_nodes $(comma_list $(mdts_nodes)) \
29633                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29634         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29635         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29636
29637         # allow remove dmv by setfattr -x
29638         do_nodes $(comma_list $(mdts_nodes)) \
29639                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29640         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29641         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29642         do_nodes $(comma_list $(mdts_nodes)) \
29643                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29644 }
29645 run_test 413j "set default LMV by setxattr"
29646
29647 test_413k() {
29648         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29649                 skip "Need server version at least 2.15.60"
29650
29651         local index1
29652         local index2
29653         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29654         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29655         local prefixes="abc:123:foo bar"
29656
29657         # add prefixes
29658         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29659         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29660
29661         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29662         index1=$($LFS getstripe -m $DIR/$tdir)
29663         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29664                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29665                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29666                 ((index1 == index2)) ||
29667                         error "$tdir on MDT$index1, $dname on MDT$index2"
29668         done
29669
29670         # remove prefixes
29671         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29672
29673         # total prefixes length > PAGE_SIZE can be printed correctly
29674         for c in {a..z}; do
29675                 prefixes=$(str_repeat $c 255)
29676                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29677         done
29678         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29679         ((count2 == count + 26)) ||
29680                 error "prefixes count $count2 != $((count + 26))"
29681 }
29682 run_test 413k "QoS mkdir exclude prefixes"
29683
29684 test_413z() {
29685         local pids=""
29686         local subdir
29687         local pid
29688
29689         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29690                 unlinkmany $subdir/f. $TEST413_COUNT &
29691                 pids="$pids $!"
29692         done
29693
29694         for pid in $pids; do
29695                 wait $pid
29696         done
29697
29698         true
29699 }
29700 run_test 413z "413 test cleanup"
29701
29702 test_414() {
29703 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29704         $LCTL set_param fail_loc=0x80000521
29705         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29706         rm -f $DIR/$tfile
29707         # This error path has sometimes left inflight requests dangling, so
29708         # test for this by remounting the client (umount will hang if there's
29709         # a dangling request)
29710         umount_client $MOUNT
29711         mount_client $MOUNT
29712 }
29713 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29714
29715 test_415() {
29716         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29717         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29718                 skip "Need server version at least 2.11.52"
29719
29720         # LU-11102
29721         local total=500
29722         local max=120
29723
29724         # this test may be slow on ZFS
29725         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29726
29727         # though this test is designed for striped directory, let's test normal
29728         # directory too since lock is always saved as CoS lock.
29729         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29730         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29731         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29732         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29733         wait_delete_completed_mds
29734
29735         # run a loop without concurrent touch to measure rename duration.
29736         # only for test debug/robustness, NOT part of COS functional test.
29737         local start_time=$SECONDS
29738         for ((i = 0; i < total; i++)); do
29739                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29740                         > /dev/null
29741         done
29742         local baseline=$((SECONDS - start_time))
29743         echo "rename $total files without 'touch' took $baseline sec"
29744
29745         (
29746                 while true; do
29747                         touch $DIR/$tdir
29748                 done
29749         ) &
29750         local setattr_pid=$!
29751
29752         # rename files back to original name so unlinkmany works
29753         start_time=$SECONDS
29754         for ((i = 0; i < total; i++)); do
29755                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29756                         > /dev/null
29757         done
29758         local duration=$((SECONDS - start_time))
29759
29760         kill -9 $setattr_pid
29761
29762         echo "rename $total files with 'touch' took $duration sec"
29763         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29764         (( duration <= max )) ||
29765                 error_not_in_vm "rename took $duration > $max sec"
29766 }
29767 run_test 415 "lock revoke is not missing"
29768
29769 test_416() {
29770         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29771                 skip "Need server version at least 2.11.55"
29772
29773         # define OBD_FAIL_OSD_TXN_START    0x19a
29774         do_facet mds1 lctl set_param fail_loc=0x19a
29775
29776         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29777
29778         true
29779 }
29780 run_test 416 "transaction start failure won't cause system hung"
29781
29782 cleanup_417() {
29783         trap 0
29784         do_nodes $(comma_list $(mdts_nodes)) \
29785                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29786         do_nodes $(comma_list $(mdts_nodes)) \
29787                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29788         do_nodes $(comma_list $(mdts_nodes)) \
29789                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29790 }
29791
29792 test_417() {
29793         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29794         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29795                 skip "Need MDS version at least 2.11.56"
29796
29797         trap cleanup_417 RETURN EXIT
29798
29799         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29800         do_nodes $(comma_list $(mdts_nodes)) \
29801                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29802         $LFS migrate -m 0 $DIR/$tdir.1 &&
29803                 error "migrate dir $tdir.1 should fail"
29804
29805         do_nodes $(comma_list $(mdts_nodes)) \
29806                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29807         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29808                 error "create remote dir $tdir.2 should fail"
29809
29810         do_nodes $(comma_list $(mdts_nodes)) \
29811                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29812         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29813                 error "create striped dir $tdir.3 should fail"
29814         true
29815 }
29816 run_test 417 "disable remote dir, striped dir and dir migration"
29817
29818 # Checks that the outputs of df [-i] and lfs df [-i] match
29819 #
29820 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29821 check_lfs_df() {
29822         local dir=$2
29823         local inodes
29824         local df_out
29825         local lfs_df_out
29826         local count
29827         local passed=false
29828
29829         # blocks or inodes
29830         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29831
29832         for count in {1..100}; do
29833                 do_nodes "$CLIENTS" \
29834                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29835                 sync; sleep 0.2
29836
29837                 # read the lines of interest
29838                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29839                         error "df $inodes $dir | tail -n +2 failed"
29840                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29841                         error "lfs df $inodes $dir | grep summary: failed"
29842
29843                 # skip first substrings of each output as they are different
29844                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29845                 # compare the two outputs
29846                 passed=true
29847                 #  skip "available" on MDT until LU-13997 is fixed.
29848                 #for i in {1..5}; do
29849                 for i in 1 2 4 5; do
29850                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29851                 done
29852                 $passed && break
29853         done
29854
29855         if ! $passed; then
29856                 df -P $inodes $dir
29857                 echo
29858                 lfs df $inodes $dir
29859                 error "df and lfs df $1 output mismatch: "      \
29860                       "df ${inodes}: ${df_out[*]}, "            \
29861                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29862         fi
29863 }
29864
29865 test_418() {
29866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29867
29868         local dir=$DIR/$tdir
29869         local numfiles=$((RANDOM % 4096 + 2))
29870         local numblocks=$((RANDOM % 256 + 1))
29871
29872         wait_delete_completed
29873         test_mkdir $dir
29874
29875         # check block output
29876         check_lfs_df blocks $dir
29877         # check inode output
29878         check_lfs_df inodes $dir
29879
29880         # create a single file and retest
29881         echo "Creating a single file and testing"
29882         createmany -o $dir/$tfile- 1 &>/dev/null ||
29883                 error "creating 1 file in $dir failed"
29884         check_lfs_df blocks $dir
29885         check_lfs_df inodes $dir
29886
29887         # create a random number of files
29888         echo "Creating $((numfiles - 1)) files and testing"
29889         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29890                 error "creating $((numfiles - 1)) files in $dir failed"
29891
29892         # write a random number of blocks to the first test file
29893         echo "Writing $numblocks 4K blocks and testing"
29894         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29895                 count=$numblocks &>/dev/null ||
29896                 error "dd to $dir/${tfile}-0 failed"
29897
29898         # retest
29899         check_lfs_df blocks $dir
29900         check_lfs_df inodes $dir
29901
29902         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29903                 error "unlinking $numfiles files in $dir failed"
29904 }
29905 run_test 418 "df and lfs df outputs match"
29906
29907 test_419()
29908 {
29909         local dir=$DIR/$tdir
29910
29911         mkdir -p $dir
29912         touch $dir/file
29913
29914         cancel_lru_locks mdc
29915
29916         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29917         $LCTL set_param fail_loc=0x1410
29918         cat $dir/file
29919         $LCTL set_param fail_loc=0
29920         rm -rf $dir
29921 }
29922 run_test 419 "Verify open file by name doesn't crash kernel"
29923
29924 test_420()
29925 {
29926         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29927                 skip "Need MDS version at least 2.12.53"
29928
29929         local SAVE_UMASK=$(umask)
29930         local dir=$DIR/$tdir
29931         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29932
29933         mkdir -p $dir
29934         umask 0000
29935         mkdir -m03777 $dir/testdir
29936         ls -dn $dir/testdir
29937         # Need to remove trailing '.' when SELinux is enabled
29938         local dirperms=$(ls -dn $dir/testdir |
29939                          awk '{ sub(/\.$/, "", $1); print $1}')
29940         [ $dirperms == "drwxrwsrwt" ] ||
29941                 error "incorrect perms on $dir/testdir"
29942
29943         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29944                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29945         ls -n $dir/testdir/testfile
29946         local fileperms=$(ls -n $dir/testdir/testfile |
29947                           awk '{ sub(/\.$/, "", $1); print $1}')
29948         [ $fileperms == "-rwxr-xr-x" ] ||
29949                 error "incorrect perms on $dir/testdir/testfile"
29950
29951         umask $SAVE_UMASK
29952 }
29953 run_test 420 "clear SGID bit on non-directories for non-members"
29954
29955 test_421a() {
29956         local cnt
29957         local fid1
29958         local fid2
29959
29960         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29961                 skip "Need MDS version at least 2.12.54"
29962
29963         test_mkdir $DIR/$tdir
29964         createmany -o $DIR/$tdir/f 3
29965         cnt=$(ls -1 $DIR/$tdir | wc -l)
29966         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29967
29968         fid1=$(lfs path2fid $DIR/$tdir/f1)
29969         fid2=$(lfs path2fid $DIR/$tdir/f2)
29970         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29971
29972         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29973         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29974
29975         cnt=$(ls -1 $DIR/$tdir | wc -l)
29976         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29977
29978         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29979         createmany -o $DIR/$tdir/f 3
29980         cnt=$(ls -1 $DIR/$tdir | wc -l)
29981         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29982
29983         fid1=$(lfs path2fid $DIR/$tdir/f1)
29984         fid2=$(lfs path2fid $DIR/$tdir/f2)
29985         echo "remove using fsname $FSNAME"
29986         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29987
29988         cnt=$(ls -1 $DIR/$tdir | wc -l)
29989         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29990 }
29991 run_test 421a "simple rm by fid"
29992
29993 test_421b() {
29994         local cnt
29995         local FID1
29996         local FID2
29997
29998         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29999                 skip "Need MDS version at least 2.12.54"
30000
30001         test_mkdir $DIR/$tdir
30002         createmany -o $DIR/$tdir/f 3
30003         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
30004         MULTIPID=$!
30005
30006         FID1=$(lfs path2fid $DIR/$tdir/f1)
30007         FID2=$(lfs path2fid $DIR/$tdir/f2)
30008         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
30009
30010         kill -USR1 $MULTIPID
30011         wait
30012
30013         cnt=$(ls $DIR/$tdir | wc -l)
30014         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
30015 }
30016 run_test 421b "rm by fid on open file"
30017
30018 test_421c() {
30019         local cnt
30020         local FIDS
30021
30022         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30023                 skip "Need MDS version at least 2.12.54"
30024
30025         test_mkdir $DIR/$tdir
30026         createmany -o $DIR/$tdir/f 3
30027         touch $DIR/$tdir/$tfile
30028         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
30029         cnt=$(ls -1 $DIR/$tdir | wc -l)
30030         [ $cnt != 184 ] && error "unexpected #files: $cnt"
30031
30032         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
30033         $LFS rmfid $DIR $FID1 || error "rmfid failed"
30034
30035         cnt=$(ls $DIR/$tdir | wc -l)
30036         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
30037 }
30038 run_test 421c "rm by fid against hardlinked files"
30039
30040 test_421d() {
30041         local cnt
30042         local FIDS
30043
30044         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30045                 skip "Need MDS version at least 2.12.54"
30046
30047         test_mkdir $DIR/$tdir
30048         createmany -o $DIR/$tdir/f 4097
30049         cnt=$(ls -1 $DIR/$tdir | wc -l)
30050         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
30051
30052         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
30053         $LFS rmfid $DIR $FIDS || error "rmfid failed"
30054
30055         cnt=$(ls $DIR/$tdir | wc -l)
30056         rm -rf $DIR/$tdir
30057         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30058 }
30059 run_test 421d "rmfid en masse"
30060
30061 test_421e() {
30062         local cnt
30063         local FID
30064
30065         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30066         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30067                 skip "Need MDS version at least 2.12.54"
30068
30069         mkdir -p $DIR/$tdir
30070         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30071         createmany -o $DIR/$tdir/striped_dir/f 512
30072         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30073         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30074
30075         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30076                 sed "s/[/][^:]*://g")
30077         $LFS rmfid $DIR $FIDS || error "rmfid failed"
30078
30079         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30080         rm -rf $DIR/$tdir
30081         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30082 }
30083 run_test 421e "rmfid in DNE"
30084
30085 test_421f() {
30086         local cnt
30087         local FID
30088
30089         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30090                 skip "Need MDS version at least 2.12.54"
30091
30092         test_mkdir $DIR/$tdir
30093         touch $DIR/$tdir/f
30094         cnt=$(ls -1 $DIR/$tdir | wc -l)
30095         [ $cnt != 1 ] && error "unexpected #files: $cnt"
30096
30097         FID=$(lfs path2fid $DIR/$tdir/f)
30098         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
30099         # rmfid should fail
30100         cnt=$(ls -1 $DIR/$tdir | wc -l)
30101         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
30102
30103         chmod a+rw $DIR/$tdir
30104         ls -la $DIR/$tdir
30105         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
30106         # rmfid should fail
30107         cnt=$(ls -1 $DIR/$tdir | wc -l)
30108         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
30109
30110         rm -f $DIR/$tdir/f
30111         $RUNAS touch $DIR/$tdir/f
30112         FID=$(lfs path2fid $DIR/$tdir/f)
30113         echo "rmfid as root"
30114         $LFS rmfid $DIR $FID || error "rmfid as root failed"
30115         cnt=$(ls -1 $DIR/$tdir | wc -l)
30116         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
30117
30118         rm -f $DIR/$tdir/f
30119         $RUNAS touch $DIR/$tdir/f
30120         cnt=$(ls -1 $DIR/$tdir | wc -l)
30121         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
30122         FID=$(lfs path2fid $DIR/$tdir/f)
30123         # rmfid w/o user_fid2path mount option should fail
30124         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
30125         cnt=$(ls -1 $DIR/$tdir | wc -l)
30126         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
30127
30128         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
30129         stack_trap "rmdir $tmpdir"
30130         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
30131                 error "failed to mount client'"
30132         stack_trap "umount_client $tmpdir"
30133
30134         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
30135         # rmfid should succeed
30136         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
30137         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
30138
30139         # rmfid shouldn't allow to remove files due to dir's permission
30140         chmod a+rwx $tmpdir/$tdir
30141         touch $tmpdir/$tdir/f
30142         ls -la $tmpdir/$tdir
30143         FID=$(lfs path2fid $tmpdir/$tdir/f)
30144         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
30145         return 0
30146 }
30147 run_test 421f "rmfid checks permissions"
30148
30149 test_421g() {
30150         local cnt
30151         local FIDS
30152
30153         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30154         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30155                 skip "Need MDS version at least 2.12.54"
30156
30157         mkdir -p $DIR/$tdir
30158         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30159         createmany -o $DIR/$tdir/striped_dir/f 512
30160         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30161         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30162
30163         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30164                 sed "s/[/][^:]*://g")
30165
30166         rm -f $DIR/$tdir/striped_dir/f1*
30167         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30168         removed=$((512 - cnt))
30169
30170         # few files have been just removed, so we expect
30171         # rmfid to fail on their fids
30172         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30173         [ $removed != $errors ] && error "$errors != $removed"
30174
30175         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30176         rm -rf $DIR/$tdir
30177         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30178 }
30179 run_test 421g "rmfid to return errors properly"
30180
30181 test_421h() {
30182         local mount_other
30183         local mount_ret
30184         local rmfid_ret
30185         local old_fid
30186         local fidA
30187         local fidB
30188         local fidC
30189         local fidD
30190
30191         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30192                 skip "Need MDS version at least 2.15.53"
30193
30194         test_mkdir $DIR/$tdir
30195         test_mkdir $DIR/$tdir/subdir
30196         touch $DIR/$tdir/subdir/file0
30197         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30198         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30199         rm -f $DIR/$tdir/subdir/file0
30200         touch $DIR/$tdir/subdir/fileA
30201         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30202         echo File $DIR/$tdir/subdir/fileA FID $fidA
30203         touch $DIR/$tdir/subdir/fileB
30204         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30205         echo File $DIR/$tdir/subdir/fileB FID $fidB
30206         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30207         touch $DIR/$tdir/subdir/fileC
30208         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30209         echo File $DIR/$tdir/subdir/fileC FID $fidC
30210         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30211         touch $DIR/$tdir/fileD
30212         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30213         echo File $DIR/$tdir/fileD FID $fidD
30214
30215         # mount another client mount point with subdirectory mount
30216         export FILESET=/$tdir/subdir
30217         mount_other=${MOUNT}_other
30218         mount_client $mount_other ${MOUNT_OPTS}
30219         mount_ret=$?
30220         export FILESET=""
30221         (( mount_ret == 0 )) || error "mount $mount_other failed"
30222
30223         echo Removing FIDs:
30224         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30225         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30226         rmfid_ret=$?
30227
30228         umount_client $mount_other || error "umount $mount_other failed"
30229
30230         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30231
30232         # fileA should have been deleted
30233         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30234
30235         # fileB should have been deleted
30236         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30237
30238         # fileC should not have been deleted, fid also exists outside of fileset
30239         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30240
30241         # fileD should not have been deleted, it exists outside of fileset
30242         stat $DIR/$tdir/fileD || error "fileD deleted"
30243 }
30244 run_test 421h "rmfid with fileset mount"
30245
30246 test_422() {
30247         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30248         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30249         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30250         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30251         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30252
30253         local amc=$(at_max_get client)
30254         local amo=$(at_max_get mds1)
30255         local timeout=`lctl get_param -n timeout`
30256
30257         at_max_set 0 client
30258         at_max_set 0 mds1
30259
30260 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30261         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30262                         fail_val=$(((2*timeout + 10)*1000))
30263         touch $DIR/$tdir/d3/file &
30264         sleep 2
30265 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30266         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30267                         fail_val=$((2*timeout + 5))
30268         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30269         local pid=$!
30270         sleep 1
30271         kill -9 $pid
30272         sleep $((2 * timeout))
30273         echo kill $pid
30274         kill -9 $pid
30275         lctl mark touch
30276         touch $DIR/$tdir/d2/file3
30277         touch $DIR/$tdir/d2/file4
30278         touch $DIR/$tdir/d2/file5
30279
30280         wait
30281         at_max_set $amc client
30282         at_max_set $amo mds1
30283
30284         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30285         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30286                 error "Watchdog is always throttled"
30287 }
30288 run_test 422 "kill a process with RPC in progress"
30289
30290 stat_test() {
30291     df -h $MOUNT &
30292     df -h $MOUNT &
30293     df -h $MOUNT &
30294     df -h $MOUNT &
30295     df -h $MOUNT &
30296     df -h $MOUNT &
30297 }
30298
30299 test_423() {
30300     local _stats
30301     # ensure statfs cache is expired
30302     sleep 2;
30303
30304     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30305     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30306
30307     return 0
30308 }
30309 run_test 423 "statfs should return a right data"
30310
30311 test_424() {
30312 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30313         $LCTL set_param fail_loc=0x80000522
30314         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30315         rm -f $DIR/$tfile
30316 }
30317 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30318
30319 test_425() {
30320         test_mkdir -c -1 $DIR/$tdir
30321         $LFS setstripe -c -1 $DIR/$tdir
30322
30323         lru_resize_disable "" 100
30324         stack_trap "lru_resize_enable" EXIT
30325
30326         sleep 5
30327
30328         for i in $(seq $((MDSCOUNT * 125))); do
30329                 local t=$DIR/$tdir/$tfile_$i
30330
30331                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30332                         error_noexit "Create file $t"
30333         done
30334         stack_trap "rm -rf $DIR/$tdir" EXIT
30335
30336         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30337                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30338                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30339
30340                 [ $lock_count -le $lru_size ] ||
30341                         error "osc lock count $lock_count > lru size $lru_size"
30342         done
30343
30344         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30345                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30346                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30347
30348                 [ $lock_count -le $lru_size ] ||
30349                         error "mdc lock count $lock_count > lru size $lru_size"
30350         done
30351 }
30352 run_test 425 "lock count should not exceed lru size"
30353
30354 test_426() {
30355         splice-test -r $DIR/$tfile
30356         splice-test -rd $DIR/$tfile
30357         splice-test $DIR/$tfile
30358         splice-test -d $DIR/$tfile
30359 }
30360 run_test 426 "splice test on Lustre"
30361
30362 test_427() {
30363         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30364         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30365                 skip "Need MDS version at least 2.12.4"
30366         local log
30367
30368         mkdir $DIR/$tdir
30369         mkdir $DIR/$tdir/1
30370         mkdir $DIR/$tdir/2
30371         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30372         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30373
30374         $LFS getdirstripe $DIR/$tdir/1/dir
30375
30376         #first setfattr for creating updatelog
30377         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30378
30379 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30380         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30381         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30382         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30383
30384         sleep 2
30385         fail mds2
30386         wait_recovery_complete mds2 $((2*TIMEOUT))
30387
30388         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30389         echo $log | grep "get update log failed" &&
30390                 error "update log corruption is detected" || true
30391 }
30392 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30393
30394 test_428() {
30395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30396         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30397                               awk '/^max_cached_mb/ { print $2 }')
30398         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30399
30400         $LCTL set_param -n llite.*.max_cached_mb=64
30401
30402         mkdir $DIR/$tdir
30403         $LFS setstripe -c 1 $DIR/$tdir
30404         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30405         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30406         #test write
30407         for f in $(seq 4); do
30408                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30409         done
30410         wait
30411
30412         cancel_lru_locks osc
30413         # Test read
30414         for f in $(seq 4); do
30415                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30416         done
30417         wait
30418 }
30419 run_test 428 "large block size IO should not hang"
30420
30421 test_429() { # LU-7915 / LU-10948
30422         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30423         local testfile=$DIR/$tfile
30424         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30425         local new_flag=1
30426         local first_rpc
30427         local second_rpc
30428         local third_rpc
30429
30430         $LCTL get_param $ll_opencache_threshold_count ||
30431                 skip "client does not have opencache parameter"
30432
30433         set_opencache $new_flag
30434         stack_trap "restore_opencache"
30435         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30436                 error "enable opencache failed"
30437         touch $testfile
30438         # drop MDC DLM locks
30439         cancel_lru_locks mdc
30440         # clear MDC RPC stats counters
30441         $LCTL set_param $mdc_rpcstats=clear
30442
30443         # According to the current implementation, we need to run 3 times
30444         # open & close file to verify if opencache is enabled correctly.
30445         # 1st, RPCs are sent for lookup/open and open handle is released on
30446         #      close finally.
30447         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30448         #      so open handle won't be released thereafter.
30449         # 3rd, No RPC is sent out.
30450         $MULTIOP $testfile oc || error "multiop failed"
30451         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30452         echo "1st: $first_rpc RPCs in flight"
30453
30454         $MULTIOP $testfile oc || error "multiop failed"
30455         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30456         echo "2nd: $second_rpc RPCs in flight"
30457
30458         $MULTIOP $testfile oc || error "multiop failed"
30459         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30460         echo "3rd: $third_rpc RPCs in flight"
30461
30462         #verify no MDC RPC is sent
30463         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30464 }
30465 run_test 429 "verify if opencache flag on client side does work"
30466
30467 lseek_test_430() {
30468         local offset
30469         local file=$1
30470
30471         # data at [200K, 400K)
30472         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30473                 error "256K->512K dd fails"
30474         # data at [2M, 3M)
30475         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30476                 error "2M->3M dd fails"
30477         # data at [4M, 5M)
30478         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30479                 error "4M->5M dd fails"
30480         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30481         # start at first component hole #1
30482         printf "Seeking hole from 1000 ... "
30483         offset=$(lseek_test -l 1000 $file)
30484         echo $offset
30485         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30486         printf "Seeking data from 1000 ... "
30487         offset=$(lseek_test -d 1000 $file)
30488         echo $offset
30489         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30490
30491         # start at first component data block
30492         printf "Seeking hole from 300000 ... "
30493         offset=$(lseek_test -l 300000 $file)
30494         echo $offset
30495         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30496         printf "Seeking data from 300000 ... "
30497         offset=$(lseek_test -d 300000 $file)
30498         echo $offset
30499         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30500
30501         # start at the first component but beyond end of object size
30502         printf "Seeking hole from 1000000 ... "
30503         offset=$(lseek_test -l 1000000 $file)
30504         echo $offset
30505         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30506         printf "Seeking data from 1000000 ... "
30507         offset=$(lseek_test -d 1000000 $file)
30508         echo $offset
30509         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30510
30511         # start at second component stripe 2 (empty file)
30512         printf "Seeking hole from 1500000 ... "
30513         offset=$(lseek_test -l 1500000 $file)
30514         echo $offset
30515         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30516         printf "Seeking data from 1500000 ... "
30517         offset=$(lseek_test -d 1500000 $file)
30518         echo $offset
30519         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30520
30521         # start at second component stripe 1 (all data)
30522         printf "Seeking hole from 3000000 ... "
30523         offset=$(lseek_test -l 3000000 $file)
30524         echo $offset
30525         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30526         printf "Seeking data from 3000000 ... "
30527         offset=$(lseek_test -d 3000000 $file)
30528         echo $offset
30529         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30530
30531         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30532                 error "2nd dd fails"
30533         echo "Add data block at 640K...1280K"
30534
30535         # start at before new data block, in hole
30536         printf "Seeking hole from 600000 ... "
30537         offset=$(lseek_test -l 600000 $file)
30538         echo $offset
30539         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30540         printf "Seeking data from 600000 ... "
30541         offset=$(lseek_test -d 600000 $file)
30542         echo $offset
30543         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30544
30545         # start at the first component new data block
30546         printf "Seeking hole from 1000000 ... "
30547         offset=$(lseek_test -l 1000000 $file)
30548         echo $offset
30549         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30550         printf "Seeking data from 1000000 ... "
30551         offset=$(lseek_test -d 1000000 $file)
30552         echo $offset
30553         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30554
30555         # start at second component stripe 2, new data
30556         printf "Seeking hole from 1200000 ... "
30557         offset=$(lseek_test -l 1200000 $file)
30558         echo $offset
30559         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30560         printf "Seeking data from 1200000 ... "
30561         offset=$(lseek_test -d 1200000 $file)
30562         echo $offset
30563         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30564
30565         # start beyond file end
30566         printf "Using offset > filesize ... "
30567         lseek_test -l 4000000 $file && error "lseek should fail"
30568         printf "Using offset > filesize ... "
30569         lseek_test -d 4000000 $file && error "lseek should fail"
30570
30571         printf "Done\n\n"
30572 }
30573
30574 test_430a() {
30575         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30576                 skip "MDT does not support SEEK_HOLE"
30577
30578         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30579                 skip "OST does not support SEEK_HOLE"
30580
30581         local file=$DIR/$tdir/$tfile
30582
30583         mkdir -p $DIR/$tdir
30584
30585         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30586         # OST stripe #1 will have continuous data at [1M, 3M)
30587         # OST stripe #2 is empty
30588         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30589         lseek_test_430 $file
30590         rm $file
30591         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30592         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30593         lseek_test_430 $file
30594         rm $file
30595         $LFS setstripe -c2 -S 512K $file
30596         echo "Two stripes, stripe size 512K"
30597         lseek_test_430 $file
30598         rm $file
30599         # FLR with stale mirror
30600         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30601                        -N -c2 -S 1M $file
30602         echo "Mirrored file:"
30603         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30604         echo "Plain 2 stripes 1M"
30605         lseek_test_430 $file
30606         rm $file
30607 }
30608 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30609
30610 test_430b() {
30611         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30612                 skip "OST does not support SEEK_HOLE"
30613
30614         local offset
30615         local file=$DIR/$tdir/$tfile
30616
30617         mkdir -p $DIR/$tdir
30618         # Empty layout lseek should fail
30619         $MCREATE $file
30620         # seek from 0
30621         printf "Seeking hole from 0 ... "
30622         lseek_test -l 0 $file && error "lseek should fail"
30623         printf "Seeking data from 0 ... "
30624         lseek_test -d 0 $file && error "lseek should fail"
30625         rm $file
30626
30627         # 1M-hole file
30628         $LFS setstripe -E 1M -c2 -E eof $file
30629         $TRUNCATE $file 1048576
30630         printf "Seeking hole from 1000000 ... "
30631         offset=$(lseek_test -l 1000000 $file)
30632         echo $offset
30633         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30634         printf "Seeking data from 1000000 ... "
30635         lseek_test -d 1000000 $file && error "lseek should fail"
30636         rm $file
30637
30638         # full component followed by non-inited one
30639         $LFS setstripe -E 1M -c2 -E eof $file
30640         dd if=/dev/urandom of=$file bs=1M count=1
30641         printf "Seeking hole from 1000000 ... "
30642         offset=$(lseek_test -l 1000000 $file)
30643         echo $offset
30644         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30645         printf "Seeking hole from 1048576 ... "
30646         lseek_test -l 1048576 $file && error "lseek should fail"
30647         # init second component and truncate back
30648         echo "123" >> $file
30649         $TRUNCATE $file 1048576
30650         printf "Seeking hole from 1000000 ... "
30651         offset=$(lseek_test -l 1000000 $file)
30652         echo $offset
30653         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30654         printf "Seeking hole from 1048576 ... "
30655         lseek_test -l 1048576 $file && error "lseek should fail"
30656         # boundary checks for big values
30657         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30658         offset=$(lseek_test -d 0 $file.10g)
30659         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30660         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30661         offset=$(lseek_test -d 0 $file.100g)
30662         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30663         return 0
30664 }
30665 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30666
30667 test_430c() {
30668         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30669                 skip "OST does not support SEEK_HOLE"
30670
30671         local file=$DIR/$tdir/$tfile
30672         local start
30673
30674         mkdir -p $DIR/$tdir
30675         stack_trap "rm -f $file $file.tmp"
30676         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30677
30678         # cp version 8.33+ prefers lseek over fiemap
30679         local ver=$(cp --version | awk '{ print $4; exit; }')
30680
30681         echo "cp $ver installed"
30682         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30683                 start=$SECONDS
30684                 time cp -v $file $file.tmp || error "cp $file failed"
30685                 (( SECONDS - start < 5 )) || {
30686                         strace cp $file $file.tmp |&
30687                                 grep -E "open|read|seek|FIEMAP" |
30688                                 grep -A 100 $file
30689                         error "cp: too long runtime $((SECONDS - start))"
30690                 }
30691         else
30692                 echo "cp test skipped due to $ver < 8.33"
30693         fi
30694
30695         # tar version 1.29+ supports SEEK_HOLE/DATA
30696         ver=$(tar --version | awk '{ print $4; exit; }')
30697         echo "tar $ver installed"
30698         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30699                 start=$SECONDS
30700                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30701                 (( SECONDS - start < 5 )) || {
30702                         strace tar cf $file.tmp --sparse $file |&
30703                                 grep -E "open|read|seek|FIEMAP" |
30704                                 grep -A 100 $file
30705                         error "tar: too long runtime $((SECONDS - start))"
30706                 }
30707         else
30708                 echo "tar test skipped due to $ver < 1.29"
30709         fi
30710 }
30711 run_test 430c "lseek: external tools check"
30712
30713 test_431() { # LU-14187
30714         local file=$DIR/$tdir/$tfile
30715
30716         mkdir -p $DIR/$tdir
30717         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30718         dd if=/dev/urandom of=$file bs=4k count=1
30719         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30720         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30721         #define OBD_FAIL_OST_RESTART_IO 0x251
30722         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30723         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30724         cp $file $file.0
30725         cancel_lru_locks
30726         sync_all_data
30727         echo 3 > /proc/sys/vm/drop_caches
30728         diff  $file $file.0 || error "data diff"
30729 }
30730 run_test 431 "Restart transaction for IO"
30731
30732 cleanup_test_432() {
30733         do_facet mgs $LCTL nodemap_activate 0
30734         wait_nm_sync active
30735 }
30736
30737 test_432() {
30738         local tmpdir=$TMP/dir432
30739
30740         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30741                 skip "Need MDS version at least 2.14.52"
30742
30743         stack_trap cleanup_test_432 EXIT
30744         mkdir $DIR/$tdir
30745         mkdir $tmpdir
30746
30747         do_facet mgs $LCTL nodemap_activate 1
30748         wait_nm_sync active
30749         do_facet mgs $LCTL nodemap_modify --name default \
30750                 --property admin --value 1
30751         do_facet mgs $LCTL nodemap_modify --name default \
30752                 --property trusted --value 1
30753         cancel_lru_locks mdc
30754         wait_nm_sync default admin_nodemap
30755         wait_nm_sync default trusted_nodemap
30756
30757         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30758                grep -ci "Operation not permitted") -ne 0 ]; then
30759                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30760         fi
30761 }
30762 run_test 432 "mv dir from outside Lustre"
30763
30764 test_433() {
30765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30766
30767         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30768                 skip "inode cache not supported"
30769
30770         $LCTL set_param llite.*.inode_cache=0
30771         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30772
30773         local count=256
30774         local before
30775         local after
30776
30777         cancel_lru_locks mdc
30778         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30779         createmany -m $DIR/$tdir/f $count
30780         createmany -d $DIR/$tdir/d $count
30781         ls -l $DIR/$tdir > /dev/null
30782         stack_trap "rm -rf $DIR/$tdir"
30783
30784         before=$(num_objects)
30785         cancel_lru_locks mdc
30786         after=$(num_objects)
30787
30788         # sometimes even @before is less than 2 * count
30789         while (( before - after < count )); do
30790                 sleep 1
30791                 after=$(num_objects)
30792                 wait=$((wait + 1))
30793                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30794                 if (( wait > 60 )); then
30795                         error "inode slab grew from $before to $after"
30796                 fi
30797         done
30798
30799         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30800 }
30801 run_test 433 "ldlm lock cancel releases dentries and inodes"
30802
30803 test_434() {
30804         local file
30805         local getxattr_count
30806         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30807         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30808
30809         [[ $(getenforce) == "Disabled" ]] ||
30810                 skip "lsm selinux module have to be disabled for this test"
30811
30812         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30813                 error "fail to create $DIR/$tdir/ on MDT0000"
30814
30815         touch $DIR/$tdir/$tfile-{001..100}
30816
30817         # disable the xattr cache
30818         save_lustre_params client "llite.*.xattr_cache" > $p
30819         lctl set_param llite.*.xattr_cache=0
30820         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30821
30822         # clear clients mdc stats
30823         clear_stats $mdc_stat_param ||
30824                 error "fail to clear stats on mdc MDT0000"
30825
30826         for file in $DIR/$tdir/$tfile-{001..100}; do
30827                 getfattr -n security.selinux $file |&
30828                         grep -q "Operation not supported" ||
30829                         error "getxattr on security.selinux should return EOPNOTSUPP"
30830         done
30831
30832         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30833         (( getxattr_count < 100 )) ||
30834                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30835 }
30836 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30837
30838 test_440() {
30839         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30840                 source $LUSTRE/scripts/bash-completion/lustre
30841         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30842                 source /usr/share/bash-completion/completions/lustre
30843         else
30844                 skip "bash completion scripts not found"
30845         fi
30846
30847         local lctl_completions
30848         local lfs_completions
30849
30850         lctl_completions=$(_lustre_cmds lctl)
30851         if [[ ! $lctl_completions =~ "get_param" ]]; then
30852                 error "lctl bash completion failed"
30853         fi
30854
30855         lfs_completions=$(_lustre_cmds lfs)
30856         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30857                 error "lfs bash completion failed"
30858         fi
30859 }
30860 run_test 440 "bash completion for lfs, lctl"
30861
30862 test_442() {
30863         local pid1
30864         local pid2
30865         mkdir -p $DIR/$tdir
30866         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30867         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30868         sleep 1
30869         touch $DIR/$tdir/$tfile.2
30870         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30871         $LCTL set_param fail_loc=0x1430
30872         kill -USR1 $pid1
30873         sleep 1
30874         kill -USR1 $pid2
30875         wait
30876 }
30877 run_test 442 "truncate vs read/write should not panic"
30878
30879 test_460d() {
30880         verify_yaml_available || skip_env "YAML verification not installed"
30881         $LCTL get_param -n sptlrpc.page_pools
30882         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30883                 error "The output of encrypt_page_pools is not an valid YAML"
30884 }
30885 run_test 460d "Check encrypt pools output"
30886
30887 prep_801() {
30888         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30889         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30890                 skip "Need server version at least 2.9.55"
30891
30892         start_full_debug_logging
30893 }
30894
30895 post_801() {
30896         stop_full_debug_logging
30897 }
30898
30899 barrier_stat() {
30900         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30901                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30902                            awk '/The barrier for/ { print $7 }')
30903                 echo $st
30904         else
30905                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30906                 echo \'$st\'
30907         fi
30908 }
30909
30910 barrier_expired() {
30911         local expired
30912
30913         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30914                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30915                           awk '/will be expired/ { print $7 }')
30916         else
30917                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30918         fi
30919
30920         echo $expired
30921 }
30922
30923 test_801a() {
30924         prep_801
30925
30926         echo "Start barrier_freeze at: $(date)"
30927         #define OBD_FAIL_BARRIER_DELAY          0x2202
30928         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30929         # Do not reduce barrier time - See LU-11873
30930         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30931
30932         sleep 2
30933         local b_status=$(barrier_stat)
30934         echo "Got barrier status at: $(date)"
30935         [ "$b_status" = "'freezing_p1'" ] ||
30936                 error "(1) unexpected barrier status $b_status"
30937
30938         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30939         wait
30940         b_status=$(barrier_stat)
30941         [ "$b_status" = "'frozen'" ] ||
30942                 error "(2) unexpected barrier status $b_status"
30943
30944         local expired=$(barrier_expired)
30945         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30946         sleep $((expired + 3))
30947
30948         b_status=$(barrier_stat)
30949         [ "$b_status" = "'expired'" ] ||
30950                 error "(3) unexpected barrier status $b_status"
30951
30952         # Do not reduce barrier time - See LU-11873
30953         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30954                 error "(4) fail to freeze barrier"
30955
30956         b_status=$(barrier_stat)
30957         [ "$b_status" = "'frozen'" ] ||
30958                 error "(5) unexpected barrier status $b_status"
30959
30960         echo "Start barrier_thaw at: $(date)"
30961         #define OBD_FAIL_BARRIER_DELAY          0x2202
30962         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30963         do_facet mgs $LCTL barrier_thaw $FSNAME &
30964
30965         sleep 2
30966         b_status=$(barrier_stat)
30967         echo "Got barrier status at: $(date)"
30968         [ "$b_status" = "'thawing'" ] ||
30969                 error "(6) unexpected barrier status $b_status"
30970
30971         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30972         wait
30973         b_status=$(barrier_stat)
30974         [ "$b_status" = "'thawed'" ] ||
30975                 error "(7) unexpected barrier status $b_status"
30976
30977         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30978         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30979         do_facet mgs $LCTL barrier_freeze $FSNAME
30980
30981         b_status=$(barrier_stat)
30982         [ "$b_status" = "'failed'" ] ||
30983                 error "(8) unexpected barrier status $b_status"
30984
30985         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30986         do_facet mgs $LCTL barrier_thaw $FSNAME
30987
30988         post_801
30989 }
30990 run_test 801a "write barrier user interfaces and stat machine"
30991
30992 test_801b() {
30993         prep_801
30994
30995         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30996         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30997         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30998         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30999         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
31000
31001         cancel_lru_locks mdc
31002
31003         # 180 seconds should be long enough
31004         do_facet mgs $LCTL barrier_freeze $FSNAME 180
31005
31006         local b_status=$(barrier_stat)
31007         [ "$b_status" = "'frozen'" ] ||
31008                 error "(6) unexpected barrier status $b_status"
31009
31010         mkdir $DIR/$tdir/d0/d10 &
31011         mkdir_pid=$!
31012
31013         touch $DIR/$tdir/d1/f13 &
31014         touch_pid=$!
31015
31016         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
31017         ln_pid=$!
31018
31019         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
31020         mv_pid=$!
31021
31022         rm -f $DIR/$tdir/d4/f12 &
31023         rm_pid=$!
31024
31025         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
31026
31027         # To guarantee taht the 'stat' is not blocked
31028         b_status=$(barrier_stat)
31029         [ "$b_status" = "'frozen'" ] ||
31030                 error "(8) unexpected barrier status $b_status"
31031
31032         # let above commands to run at background
31033         sleep 5
31034
31035         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
31036         ps -p $touch_pid || error "(10) touch should be blocked"
31037         ps -p $ln_pid || error "(11) link should be blocked"
31038         ps -p $mv_pid || error "(12) rename should be blocked"
31039         ps -p $rm_pid || error "(13) unlink should be blocked"
31040
31041         b_status=$(barrier_stat)
31042         [ "$b_status" = "'frozen'" ] ||
31043                 error "(14) unexpected barrier status $b_status"
31044
31045         do_facet mgs $LCTL barrier_thaw $FSNAME
31046         b_status=$(barrier_stat)
31047         [ "$b_status" = "'thawed'" ] ||
31048                 error "(15) unexpected barrier status $b_status"
31049
31050         wait $mkdir_pid || error "(16) mkdir should succeed"
31051         wait $touch_pid || error "(17) touch should succeed"
31052         wait $ln_pid || error "(18) link should succeed"
31053         wait $mv_pid || error "(19) rename should succeed"
31054         wait $rm_pid || error "(20) unlink should succeed"
31055
31056         post_801
31057 }
31058 run_test 801b "modification will be blocked by write barrier"
31059
31060 test_801c() {
31061         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31062
31063         prep_801
31064
31065         stop mds2 || error "(1) Fail to stop mds2"
31066
31067         do_facet mgs $LCTL barrier_freeze $FSNAME 30
31068
31069         local b_status=$(barrier_stat)
31070         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
31071                 do_facet mgs $LCTL barrier_thaw $FSNAME
31072                 error "(2) unexpected barrier status $b_status"
31073         }
31074
31075         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31076                 error "(3) Fail to rescan barrier bitmap"
31077
31078         # Do not reduce barrier time - See LU-11873
31079         do_facet mgs $LCTL barrier_freeze $FSNAME 20
31080
31081         b_status=$(barrier_stat)
31082         [ "$b_status" = "'frozen'" ] ||
31083                 error "(4) unexpected barrier status $b_status"
31084
31085         do_facet mgs $LCTL barrier_thaw $FSNAME
31086         b_status=$(barrier_stat)
31087         [ "$b_status" = "'thawed'" ] ||
31088                 error "(5) unexpected barrier status $b_status"
31089
31090         local devname=$(mdsdevname 2)
31091
31092         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
31093
31094         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31095                 error "(7) Fail to rescan barrier bitmap"
31096
31097         post_801
31098 }
31099 run_test 801c "rescan barrier bitmap"
31100
31101 test_802b() {
31102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31103         remote_mds_nodsh && skip "remote MDS with nodsh"
31104
31105         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
31106                 skip "readonly option not available"
31107
31108         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
31109
31110         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
31111                 error "(2) Fail to copy"
31112
31113         # write back all cached data before setting MDT to readonly
31114         cancel_lru_locks
31115         sync_all_data
31116
31117         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
31118         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
31119
31120         echo "Modify should be refused"
31121         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
31122
31123         echo "Read should be allowed"
31124         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
31125                 error "(7) Read should succeed under ro mode"
31126
31127         # disable readonly
31128         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
31129 }
31130 run_test 802b "be able to set MDTs to readonly"
31131
31132 test_803a() {
31133         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31134         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31135                 skip "MDS needs to be newer than 2.10.54"
31136
31137         mkdir_on_mdt0 $DIR/$tdir
31138         # Create some objects on all MDTs to trigger related logs objects
31139         for idx in $(seq $MDSCOUNT); do
31140                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
31141                         $DIR/$tdir/dir${idx} ||
31142                         error "Fail to create $DIR/$tdir/dir${idx}"
31143         done
31144
31145         wait_delete_completed # ensure old test cleanups are finished
31146         sleep 3
31147         echo "before create:"
31148         $LFS df -i $MOUNT
31149         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31150
31151         for i in {1..10}; do
31152                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31153                         error "Fail to create $DIR/$tdir/foo$i"
31154         done
31155
31156         # sync ZFS-on-MDS to refresh statfs data
31157         wait_zfs_commit mds1
31158         sleep 3
31159         echo "after create:"
31160         $LFS df -i $MOUNT
31161         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31162
31163         # allow for an llog to be cleaned up during the test
31164         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31165                 error "before ($before_used) + 10 > after ($after_used)"
31166
31167         for i in {1..10}; do
31168                 rm -rf $DIR/$tdir/foo$i ||
31169                         error "Fail to remove $DIR/$tdir/foo$i"
31170         done
31171
31172         # sync ZFS-on-MDS to refresh statfs data
31173         wait_zfs_commit mds1
31174         wait_delete_completed
31175         sleep 3 # avoid MDT return cached statfs
31176         echo "after unlink:"
31177         $LFS df -i $MOUNT
31178         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31179
31180         # allow for an llog to be created during the test
31181         [ $after_used -le $((before_used + 1)) ] ||
31182                 error "after ($after_used) > before ($before_used) + 1"
31183 }
31184 run_test 803a "verify agent object for remote object"
31185
31186 test_803b() {
31187         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31188         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31189                 skip "MDS needs to be newer than 2.13.56"
31190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31191
31192         for i in $(seq 0 $((MDSCOUNT - 1))); do
31193                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31194         done
31195
31196         local before=0
31197         local after=0
31198
31199         local tmp
31200
31201         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31202         for i in $(seq 0 $((MDSCOUNT - 1))); do
31203                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31204                         awk '/getattr/ { print $2 }')
31205                 before=$((before + tmp))
31206         done
31207         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31208         for i in $(seq 0 $((MDSCOUNT - 1))); do
31209                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31210                         awk '/getattr/ { print $2 }')
31211                 after=$((after + tmp))
31212         done
31213
31214         [ $before -eq $after ] || error "getattr count $before != $after"
31215 }
31216 run_test 803b "remote object can getattr from cache"
31217
31218 test_804() {
31219         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31220         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31221                 skip "MDS needs to be newer than 2.10.54"
31222         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31223
31224         mkdir -p $DIR/$tdir
31225         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31226                 error "Fail to create $DIR/$tdir/dir0"
31227
31228         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31229         local dev=$(mdsdevname 2)
31230
31231         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31232                 grep ${fid} || error "NOT found agent entry for dir0"
31233
31234         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31235                 error "Fail to create $DIR/$tdir/dir1"
31236
31237         touch $DIR/$tdir/dir1/foo0 ||
31238                 error "Fail to create $DIR/$tdir/dir1/foo0"
31239         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31240         local rc=0
31241
31242         for idx in $(seq $MDSCOUNT); do
31243                 dev=$(mdsdevname $idx)
31244                 do_facet mds${idx} \
31245                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31246                         grep ${fid} && rc=$idx
31247         done
31248
31249         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31250                 error "Fail to rename foo0 to foo1"
31251         if [ $rc -eq 0 ]; then
31252                 for idx in $(seq $MDSCOUNT); do
31253                         dev=$(mdsdevname $idx)
31254                         do_facet mds${idx} \
31255                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31256                         grep ${fid} && rc=$idx
31257                 done
31258         fi
31259
31260         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31261                 error "Fail to rename foo1 to foo2"
31262         if [ $rc -eq 0 ]; then
31263                 for idx in $(seq $MDSCOUNT); do
31264                         dev=$(mdsdevname $idx)
31265                         do_facet mds${idx} \
31266                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31267                         grep ${fid} && rc=$idx
31268                 done
31269         fi
31270
31271         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31272
31273         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31274                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31275         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31276                 error "Fail to rename foo2 to foo0"
31277         unlink $DIR/$tdir/dir1/foo0 ||
31278                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31279         rm -rf $DIR/$tdir/dir0 ||
31280                 error "Fail to rm $DIR/$tdir/dir0"
31281
31282         for idx in $(seq $MDSCOUNT); do
31283                 rc=0
31284
31285                 stop mds${idx}
31286                 dev=$(mdsdevname $idx)
31287                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31288                         rc=$?
31289                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31290                         error "mount mds$idx failed"
31291                 df $MOUNT > /dev/null 2>&1
31292
31293                 # e2fsck should not return error
31294                 [ $rc -eq 0 ] ||
31295                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31296         done
31297 }
31298 run_test 804 "verify agent entry for remote entry"
31299
31300 cleanup_805() {
31301         do_facet $SINGLEMDS zfs set quota=$old $fsset
31302         unlinkmany $DIR/$tdir/f- 1000000
31303         trap 0
31304 }
31305
31306 test_805() {
31307         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31308         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31309         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31310                 skip "netfree not implemented before 0.7"
31311         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31312                 skip "Need MDS version at least 2.10.57"
31313
31314         local fsset
31315         local freekb
31316         local usedkb
31317         local old
31318         local quota
31319         local pref="osd-zfs.$FSNAME-MDT0000."
31320
31321         # limit available space on MDS dataset to meet nospace issue
31322         # quickly. then ZFS 0.7.2 can use reserved space if asked
31323         # properly (using netfree flag in osd_declare_destroy()
31324         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31325         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31326                 gawk '{print $3}')
31327         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31328         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31329         let "usedkb=usedkb-freekb"
31330         let "freekb=freekb/2"
31331         if let "freekb > 5000"; then
31332                 let "freekb=5000"
31333         fi
31334         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31335         trap cleanup_805 EXIT
31336         mkdir_on_mdt0 $DIR/$tdir
31337         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31338                 error "Can't set PFL layout"
31339         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31340         rm -rf $DIR/$tdir || error "not able to remove"
31341         do_facet $SINGLEMDS zfs set quota=$old $fsset
31342         trap 0
31343 }
31344 run_test 805 "ZFS can remove from full fs"
31345
31346 # Size-on-MDS test
31347 check_lsom_data()
31348 {
31349         local file=$1
31350         local expect=$(stat -c %s $file)
31351         local msg=$2
31352
31353         check_lsom_size $1 $expect $msg
31354
31355         local blocks=$($LFS getsom -b $file)
31356         expect=$(stat -c %b $file)
31357         [[ $blocks == $expect ]] ||
31358                 error "$msg $file expected blocks: $expect, got: $blocks"
31359 }
31360
31361 check_lsom_size()
31362 {
31363         local size
31364         local expect=$2
31365         local msg=$3
31366
31367         cancel_lru_locks mdc
31368
31369         size=$($LFS getsom -s $1)
31370         [[ $size == $expect ]] ||
31371                 error "$msg $file expected size: $expect, got: $size"
31372 }
31373
31374 test_806() {
31375         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31376                 skip "Need MDS version at least 2.11.52"
31377
31378         local bs=1048576
31379
31380         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31381
31382         disable_opencache
31383         stack_trap "restore_opencache"
31384
31385         # single-threaded write
31386         echo "Test SOM for single-threaded write"
31387         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31388                 error "write $tfile failed"
31389         check_lsom_size $DIR/$tfile $bs "(0)"
31390         # Test SOM with DIO write (dd truncates to 0)
31391         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 oflag=direct ||
31392                 error "write $tfile failed"
31393         check_lsom_size $DIR/$tfile $bs "(1)"
31394
31395         local num=32
31396         local size=$(($num * $bs))
31397         local offset=0
31398         local i
31399
31400         echo "Test SOM for single client multi-threaded($num) write"
31401         $TRUNCATE $DIR/$tfile 0
31402         for ((i = 0; i < $num; i++)); do
31403                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31404                 local pids[$i]=$!
31405                 offset=$((offset + $bs))
31406         done
31407         for (( i=0; i < $num; i++ )); do
31408                 wait ${pids[$i]}
31409         done
31410         check_lsom_size $DIR/$tfile $size "(2)"
31411
31412         $TRUNCATE $DIR/$tfile 0
31413         for ((i = 0; i < $num; i++)); do
31414                 offset=$((offset - $bs))
31415                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31416                 local pids[$i]=$!
31417         done
31418         for (( i=0; i < $num; i++ )); do
31419                 wait ${pids[$i]}
31420         done
31421         check_lsom_size $DIR/$tfile $size "(3)"
31422
31423         # multi-client writes
31424         num=$(get_node_count ${CLIENTS//,/ })
31425         size=$(($num * $bs))
31426         offset=0
31427         i=0
31428
31429         echo "Test SOM for multi-client ($num) writes"
31430         $TRUNCATE $DIR/$tfile 0
31431         for client in ${CLIENTS//,/ }; do
31432                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31433                 local pids[$i]=$!
31434                 i=$((i + 1))
31435                 offset=$((offset + $bs))
31436         done
31437         for (( i=0; i < $num; i++ )); do
31438                 wait ${pids[$i]}
31439         done
31440         check_lsom_size $DIR/$tfile $offset "(4)"
31441
31442         i=0
31443         $TRUNCATE $DIR/$tfile 0
31444         for client in ${CLIENTS//,/ }; do
31445                 offset=$((offset - $bs))
31446                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31447                 local pids[$i]=$!
31448                 i=$((i + 1))
31449         done
31450         for (( i=0; i < $num; i++ )); do
31451                 wait ${pids[$i]}
31452         done
31453         check_lsom_size $DIR/$tfile $size "(5)"
31454
31455         # verify SOM blocks count
31456         echo "Verify SOM block count"
31457         $TRUNCATE $DIR/$tfile 0
31458         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31459                 error "failed to write file $tfile with fdatasync and fstat"
31460         check_lsom_data $DIR/$tfile "(6)"
31461
31462         $TRUNCATE $DIR/$tfile 0
31463         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31464                 error "failed to write file $tfile with fdatasync"
31465         check_lsom_data $DIR/$tfile "(7)"
31466
31467         $TRUNCATE $DIR/$tfile 0
31468         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31469                 error "failed to write file $tfile with sync IO"
31470         check_lsom_data $DIR/$tfile "(8)"
31471
31472         # verify truncate
31473         echo "Test SOM for truncate"
31474         # use ftruncate to sync blocks on close request
31475         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31476         check_lsom_size $DIR/$tfile 16384 "(9)"
31477         check_lsom_data $DIR/$tfile "(10)"
31478
31479         $TRUNCATE $DIR/$tfile 1234
31480         check_lsom_size $DIR/$tfile 1234 "(11)"
31481         # sync blocks on the MDT
31482         $MULTIOP $DIR/$tfile oc
31483         check_lsom_data $DIR/$tfile "(12)"
31484 }
31485 run_test 806 "Verify Lazy Size on MDS"
31486
31487 test_807() {
31488         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31489         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31490                 skip "Need MDS version at least 2.11.52"
31491
31492         # Registration step
31493         changelog_register || error "changelog_register failed"
31494         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31495         changelog_users $SINGLEMDS | grep -q $cl_user ||
31496                 error "User $cl_user not found in changelog_users"
31497
31498         rm -rf $DIR/$tdir || error "rm $tdir failed"
31499         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31500         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31501         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31502         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31503                 error "truncate $tdir/trunc failed"
31504
31505         local bs=1048576
31506         echo "Test SOM for single-threaded write with fsync"
31507         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31508                 error "write $tfile failed"
31509         sync;sync;sync
31510
31511         # multi-client wirtes
31512         local num=$(get_node_count ${CLIENTS//,/ })
31513         local offset=0
31514         local i=0
31515
31516         echo "Test SOM for multi-client ($num) writes"
31517         touch $DIR/$tfile || error "touch $tfile failed"
31518         $TRUNCATE $DIR/$tfile 0
31519         for client in ${CLIENTS//,/ }; do
31520                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31521                 local pids[$i]=$!
31522                 i=$((i + 1))
31523                 offset=$((offset + $bs))
31524         done
31525         for (( i=0; i < $num; i++ )); do
31526                 wait ${pids[$i]}
31527         done
31528
31529         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31530         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31531         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31532         check_lsom_data $DIR/$tdir/trunc "(0)"
31533         check_lsom_data $DIR/$tdir/single_dd "(1)"
31534         check_lsom_data $DIR/$tfile "(2)"
31535
31536         rm -rf $DIR/$tdir
31537         # Deregistration step
31538         changelog_deregister || error "changelog_deregister failed"
31539 }
31540 run_test 807 "verify LSOM syncing tool"
31541
31542 check_som_nologged()
31543 {
31544         local lines=$($LFS changelog $FSNAME-MDT0000 |
31545                 grep 'x=trusted.som' | wc -l)
31546         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31547 }
31548
31549 test_808() {
31550         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31551                 skip "Need MDS version at least 2.11.55"
31552
31553         # Registration step
31554         changelog_register || error "changelog_register failed"
31555
31556         touch $DIR/$tfile || error "touch $tfile failed"
31557         check_som_nologged
31558
31559         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31560                 error "write $tfile failed"
31561         check_som_nologged
31562
31563         $TRUNCATE $DIR/$tfile 1234
31564         check_som_nologged
31565
31566         $TRUNCATE $DIR/$tfile 1048576
31567         check_som_nologged
31568
31569         # Deregistration step
31570         changelog_deregister || error "changelog_deregister failed"
31571 }
31572 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31573
31574 check_som_nodata()
31575 {
31576         $LFS getsom $1
31577         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31578 }
31579
31580 test_809() {
31581         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31582                 skip "Need MDS version at least 2.11.56"
31583
31584         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31585                 error "failed to create DoM-only file $DIR/$tfile"
31586         touch $DIR/$tfile || error "touch $tfile failed"
31587         check_som_nodata $DIR/$tfile
31588
31589         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31590                 error "write $tfile failed"
31591         check_som_nodata $DIR/$tfile
31592
31593         $TRUNCATE $DIR/$tfile 1234
31594         check_som_nodata $DIR/$tfile
31595
31596         $TRUNCATE $DIR/$tfile 4097
31597         check_som_nodata $DIR/$file
31598 }
31599 run_test 809 "Verify no SOM xattr store for DoM-only files"
31600
31601 test_810() {
31602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31603         $GSS && skip_env "could not run with gss"
31604         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31605                 skip "OST < 2.12.58 doesn't align checksum"
31606
31607         set_checksums 1
31608         stack_trap "set_checksums $ORIG_CSUM" EXIT
31609         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31610
31611         local csum
31612         local before
31613         local after
31614         for csum in $CKSUM_TYPES; do
31615                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31616                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31617                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31618                         eval set -- $i
31619                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31620                         before=$(md5sum $DIR/$tfile)
31621                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31622                         after=$(md5sum $DIR/$tfile)
31623                         [ "$before" == "$after" ] ||
31624                                 error "$csum: $before != $after bs=$1 seek=$2"
31625                 done
31626         done
31627 }
31628 run_test 810 "partial page writes on ZFS (LU-11663)"
31629
31630 test_812a() {
31631         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31632                 skip "OST < 2.12.51 doesn't support this fail_loc"
31633         local old
31634
31635         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31636         $LCTL set_param osc.*.idle_timeout=10
31637         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31638
31639         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31640         # ensure ost1 is connected
31641         stat $DIR/$tfile >/dev/null || error "can't stat"
31642         wait_osc_import_state client ost1 FULL
31643         # no locks, no reqs to let the connection idle
31644         cancel_lru_locks osc
31645
31646         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31647 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31648         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31649         wait_osc_import_state client ost1 CONNECTING
31650         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31651
31652         stat $DIR/$tfile >/dev/null || error "can't stat file"
31653 }
31654 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31655
31656 test_812b() { # LU-12378
31657         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31658                 skip "OST < 2.12.51 doesn't support this fail_loc"
31659         local old
31660
31661         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31662         $LCTL set_param osc.*.idle_timeout=10
31663         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31664
31665         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31666         # ensure ost1 is connected
31667         stat $DIR/$tfile >/dev/null || error "can't stat"
31668         wait_osc_import_state client ost1 FULL
31669         # no locks, no reqs to let the connection idle
31670         cancel_lru_locks osc
31671
31672         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31673 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31674         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31675         wait_osc_import_state client ost1 CONNECTING
31676         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31677
31678         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31679         wait_osc_import_state client ost1 IDLE
31680 }
31681 run_test 812b "do not drop no resend request for idle connect"
31682
31683 test_812c() {
31684         local old
31685
31686         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31687
31688         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31689         $LFS getstripe $DIR/$tfile
31690         $LCTL set_param osc.*.idle_timeout=10
31691         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31692         # ensure ost1 is connected
31693         stat $DIR/$tfile >/dev/null || error "can't stat"
31694         wait_osc_import_state client ost1 FULL
31695         # no locks, no reqs to let the connection idle
31696         cancel_lru_locks osc
31697
31698 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31699         $LCTL set_param fail_loc=0x80000533
31700         sleep 15
31701         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31702 }
31703 run_test 812c "idle import vs lock enqueue race"
31704
31705 test_813() {
31706         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31707         [ -z "$file_heat_sav" ] && skip "no file heat support"
31708
31709         local readsample
31710         local writesample
31711         local readbyte
31712         local writebyte
31713         local readsample1
31714         local writesample1
31715         local readbyte1
31716         local writebyte1
31717
31718         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31719         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31720
31721         $LCTL set_param -n llite.*.file_heat=1
31722         echo "Turn on file heat"
31723         echo "Period second: $period_second, Decay percentage: $decay_pct"
31724
31725         echo "QQQQ" > $DIR/$tfile
31726         echo "QQQQ" > $DIR/$tfile
31727         echo "QQQQ" > $DIR/$tfile
31728         cat $DIR/$tfile > /dev/null
31729         cat $DIR/$tfile > /dev/null
31730         cat $DIR/$tfile > /dev/null
31731         cat $DIR/$tfile > /dev/null
31732
31733         local out=$($LFS heat_get $DIR/$tfile)
31734
31735         $LFS heat_get $DIR/$tfile
31736         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31737         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31738         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31739         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31740
31741         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31742         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31743         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31744         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31745
31746         sleep $((period_second + 3))
31747         echo "Sleep $((period_second + 3)) seconds..."
31748         # The recursion formula to calculate the heat of the file f is as
31749         # follow:
31750         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31751         # Where Hi is the heat value in the period between time points i*I and
31752         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31753         # to the weight of Ci.
31754         out=$($LFS heat_get $DIR/$tfile)
31755         $LFS heat_get $DIR/$tfile
31756         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31757         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31758         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31759         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31760
31761         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31762                 error "read sample ($readsample) is wrong"
31763         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31764                 error "write sample ($writesample) is wrong"
31765         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31766                 error "read bytes ($readbyte) is wrong"
31767         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31768                 error "write bytes ($writebyte) is wrong"
31769
31770         echo "QQQQ" > $DIR/$tfile
31771         echo "QQQQ" > $DIR/$tfile
31772         echo "QQQQ" > $DIR/$tfile
31773         cat $DIR/$tfile > /dev/null
31774         cat $DIR/$tfile > /dev/null
31775         cat $DIR/$tfile > /dev/null
31776         cat $DIR/$tfile > /dev/null
31777
31778         sleep $((period_second + 3))
31779         echo "Sleep $((period_second + 3)) seconds..."
31780
31781         out=$($LFS heat_get $DIR/$tfile)
31782         $LFS heat_get $DIR/$tfile
31783         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31784         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31785         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31786         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31787
31788         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31789                 4 * $decay_pct) / 100") -eq 1 ] ||
31790                 error "read sample ($readsample1) is wrong"
31791         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31792                 3 * $decay_pct) / 100") -eq 1 ] ||
31793                 error "write sample ($writesample1) is wrong"
31794         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31795                 20 * $decay_pct) / 100") -eq 1 ] ||
31796                 error "read bytes ($readbyte1) is wrong"
31797         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31798                 15 * $decay_pct) / 100") -eq 1 ] ||
31799                 error "write bytes ($writebyte1) is wrong"
31800
31801         echo "Turn off file heat for the file $DIR/$tfile"
31802         $LFS heat_set -o $DIR/$tfile
31803
31804         echo "QQQQ" > $DIR/$tfile
31805         echo "QQQQ" > $DIR/$tfile
31806         echo "QQQQ" > $DIR/$tfile
31807         cat $DIR/$tfile > /dev/null
31808         cat $DIR/$tfile > /dev/null
31809         cat $DIR/$tfile > /dev/null
31810         cat $DIR/$tfile > /dev/null
31811
31812         out=$($LFS heat_get $DIR/$tfile)
31813         $LFS heat_get $DIR/$tfile
31814         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31815         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31816         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31817         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31818
31819         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31820         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31821         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31822         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31823
31824         echo "Trun on file heat for the file $DIR/$tfile"
31825         $LFS heat_set -O $DIR/$tfile
31826
31827         echo "QQQQ" > $DIR/$tfile
31828         echo "QQQQ" > $DIR/$tfile
31829         echo "QQQQ" > $DIR/$tfile
31830         cat $DIR/$tfile > /dev/null
31831         cat $DIR/$tfile > /dev/null
31832         cat $DIR/$tfile > /dev/null
31833         cat $DIR/$tfile > /dev/null
31834
31835         out=$($LFS heat_get $DIR/$tfile)
31836         $LFS heat_get $DIR/$tfile
31837         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31838         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31839         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31840         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31841
31842         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31843         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31844         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31845         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31846
31847         $LFS heat_set -c $DIR/$tfile
31848         $LCTL set_param -n llite.*.file_heat=0
31849         echo "Turn off file heat support for the Lustre filesystem"
31850
31851         echo "QQQQ" > $DIR/$tfile
31852         echo "QQQQ" > $DIR/$tfile
31853         echo "QQQQ" > $DIR/$tfile
31854         cat $DIR/$tfile > /dev/null
31855         cat $DIR/$tfile > /dev/null
31856         cat $DIR/$tfile > /dev/null
31857         cat $DIR/$tfile > /dev/null
31858
31859         out=$($LFS heat_get $DIR/$tfile)
31860         $LFS heat_get $DIR/$tfile
31861         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31862         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31863         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31864         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31865
31866         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31867         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31868         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31869         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31870
31871         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31872         rm -f $DIR/$tfile
31873 }
31874 run_test 813 "File heat verfication"
31875
31876 test_814()
31877 {
31878         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31879         echo -n y >> $DIR/$tfile
31880         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31881         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31882 }
31883 run_test 814 "sparse cp works as expected (LU-12361)"
31884
31885 test_815()
31886 {
31887         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31888         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31889 }
31890 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31891
31892 test_816() {
31893         local ost1_imp=$(get_osc_import_name client ost1)
31894         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31895                          cut -d'.' -f2)
31896         local old
31897
31898         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31899         $LCTL set_param osc.*.idle_timeout=10
31900         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31901
31902         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31903         # ensure ost1 is connected
31904
31905         stat $DIR/$tfile >/dev/null || error "can't stat"
31906         wait_osc_import_state client ost1 FULL
31907         # no locks, no reqs to let the connection idle
31908         cancel_lru_locks osc
31909         lru_resize_disable osc
31910         local before
31911         local now
31912         before=$($LCTL get_param -n \
31913                  ldlm.namespaces.$imp_name.lru_size)
31914
31915         wait_osc_import_state client ost1 IDLE
31916         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31917         now=$($LCTL get_param -n \
31918               ldlm.namespaces.$imp_name.lru_size)
31919         [ $before == $now ] || error "lru_size changed $before != $now"
31920 }
31921 run_test 816 "do not reset lru_resize on idle reconnect"
31922
31923 cleanup_817() {
31924         umount $tmpdir
31925         exportfs -u localhost:$DIR/nfsexp
31926         rm -rf $DIR/nfsexp
31927 }
31928
31929 test_817() {
31930         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31931
31932         mkdir -p $DIR/nfsexp
31933         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31934                 error "failed to export nfs"
31935
31936         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31937         stack_trap cleanup_817 EXIT
31938
31939         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31940                 error "failed to mount nfs to $tmpdir"
31941
31942         cp /bin/true $tmpdir
31943         $DIR/nfsexp/true || error "failed to execute 'true' command"
31944 }
31945 run_test 817 "nfsd won't cache write lock for exec file"
31946
31947 test_818() {
31948         test_mkdir -i0 -c1 $DIR/$tdir
31949         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31950         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31951         stop $SINGLEMDS
31952
31953         # restore osp-syn threads
31954         stack_trap "fail $SINGLEMDS"
31955
31956         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31957         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31958         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31959                 error "start $SINGLEMDS failed"
31960         rm -rf $DIR/$tdir
31961
31962         local testid=$(echo $TESTNAME | tr '_' ' ')
31963
31964         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31965                 grep "run LFSCK" || error "run LFSCK is not suggested"
31966 }
31967 run_test 818 "unlink with failed llog"
31968
31969 test_819a() {
31970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31971         cancel_lru_locks osc
31972         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31973         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31974         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31975         rm -f $TDIR/$tfile
31976 }
31977 run_test 819a "too big niobuf in read"
31978
31979 test_819b() {
31980         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31981         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31982         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31983         cancel_lru_locks osc
31984         sleep 1
31985         rm -f $TDIR/$tfile
31986 }
31987 run_test 819b "too big niobuf in write"
31988
31989
31990 function test_820_start_ost() {
31991         sleep 5
31992
31993         for num in $(seq $OSTCOUNT); do
31994                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31995         done
31996 }
31997
31998 test_820() {
31999         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
32000
32001         mkdir $DIR/$tdir
32002         umount_client $MOUNT || error "umount failed"
32003         for num in $(seq $OSTCOUNT); do
32004                 stop ost$num
32005         done
32006
32007         # mount client with no active OSTs
32008         # so that the client can't initialize max LOV EA size
32009         # from OSC notifications
32010         mount_client $MOUNT || error "mount failed"
32011         # delay OST starting to keep this 0 max EA size for a while
32012         test_820_start_ost &
32013
32014         # create a directory on MDS2
32015         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
32016                 error "Failed to create directory"
32017         # open intent should update default EA size
32018         # see mdc_update_max_ea_from_body()
32019         # notice this is the very first RPC to MDS2
32020         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
32021         ret=$?
32022         echo $out
32023         # With SSK, this situation can lead to -EPERM being returned.
32024         # In that case, simply retry.
32025         if [ $ret -ne 0 ] && $SHARED_KEY; then
32026                 if echo "$out" | grep -q "not permitted"; then
32027                         cp /etc/services $DIR/$tdir/mds2
32028                         ret=$?
32029                 fi
32030         fi
32031         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
32032 }
32033 run_test 820 "update max EA from open intent"
32034
32035 test_823() {
32036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
32037         local OST_MAX_PRECREATE=20000
32038
32039         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
32040                 skip "Need MDS version at least 2.14.56"
32041
32042         save_lustre_params mds1 \
32043                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
32044         do_facet $SINGLEMDS "$LCTL set_param -n \
32045                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
32046         do_facet $SINGLEMDS "$LCTL set_param -n \
32047                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
32048
32049         stack_trap "restore_lustre_params < $p; rm $p"
32050
32051         do_facet $SINGLEMDS "$LCTL set_param -n \
32052                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
32053
32054         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
32055                       osp.$FSNAME-OST0000*MDT0000.create_count")
32056         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
32057                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
32058         local expect_count=$(((($max/2)/256) * 256))
32059
32060         log "setting create_count to 100200:"
32061         log " -result- count: $count with max: $max, expecting: $expect_count"
32062
32063         [[ $count -eq expect_count ]] ||
32064                 error "Create count not set to max precreate."
32065 }
32066 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
32067
32068 test_831() {
32069         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
32070                 skip "Need MDS version 2.14.56"
32071
32072         local sync_changes=$(do_facet $SINGLEMDS \
32073                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32074
32075         [ "$sync_changes" -gt 100 ] &&
32076                 skip "Sync changes $sync_changes > 100 already"
32077
32078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
32079
32080         $LFS mkdir -i 0 $DIR/$tdir
32081         $LFS setstripe -c 1 -i 0 $DIR/$tdir
32082
32083         save_lustre_params mds1 \
32084                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
32085         save_lustre_params mds1 \
32086                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
32087
32088         do_facet mds1 "$LCTL set_param -n \
32089                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
32090                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
32091         stack_trap "restore_lustre_params < $p" EXIT
32092
32093         createmany -o $DIR/$tdir/f- 1000
32094         unlinkmany $DIR/$tdir/f- 1000 &
32095         local UNLINK_PID=$!
32096
32097         while sleep 1; do
32098                 sync_changes=$(do_facet mds1 \
32099                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32100                 # the check in the code is racy, fail the test
32101                 # if the value above the limit by 10.
32102                 [ $sync_changes -gt 110 ] && {
32103                         kill -2 $UNLINK_PID
32104                         wait
32105                         error "osp changes throttling failed, $sync_changes>110"
32106                 }
32107                 kill -0 $UNLINK_PID 2> /dev/null || break
32108         done
32109         wait
32110 }
32111 run_test 831 "throttling unlink/setattr queuing on OSP"
32112
32113 test_832() {
32114         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32115         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
32116                 skip "Need MDS version 2.15.52+"
32117         is_rmentry_supported || skip "rm_entry not supported"
32118
32119         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
32120         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
32121         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
32122                 error "mkdir remote_dir failed"
32123         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
32124                 error "mkdir striped_dir failed"
32125         touch $DIR/$tdir/file || error "touch file failed"
32126         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
32127         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
32128 }
32129 run_test 832 "lfs rm_entry"
32130
32131 test_833() {
32132         local file=$DIR/$tfile
32133
32134         stack_trap "rm -f $file" EXIT
32135         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
32136
32137         local wpid
32138         local rpid
32139         local rpid2
32140
32141         # Buffered I/O write
32142         (
32143                 while [ ! -e $DIR/sanity.833.lck ]; do
32144                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
32145                                 error "failed to write $file"
32146                         sleep 0.$((RANDOM % 4 + 1))
32147                 done
32148         )&
32149         wpid=$!
32150
32151         # Buffered I/O read
32152         (
32153                 while [ ! -e $DIR/sanity.833.lck ]; do
32154                         dd if=$file of=/dev/null bs=1M count=50 ||
32155                                 error "failed to read $file"
32156                         sleep 0.$((RANDOM % 4 + 1))
32157                 done
32158         )&
32159         rpid=$!
32160
32161         # Direct I/O read
32162         (
32163                 while [ ! -e $DIR/sanity.833.lck ]; do
32164                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32165                                 error "failed to read $file in direct I/O mode"
32166                         sleep 0.$((RANDOM % 4 + 1))
32167                 done
32168         )&
32169         rpid2=$!
32170
32171         sleep 30
32172         touch $DIR/sanity.833.lck
32173         wait $wpid || error "$?: buffered write failed"
32174         wait $rpid || error "$?: buffered read failed"
32175         wait $rpid2 || error "$?: direct read failed"
32176 }
32177 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32178
32179 test_842() {
32180         local oss1=$(facet_host ost1)
32181
32182         # Try to insert the module.  This will leave results in dmesg
32183         now=$(date +%s)
32184         log "STAMP $now" > /dev/kmsg
32185         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32186                 error "$oss1 load_module ldlm_extent failed"
32187
32188         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32189         do_node $oss1 rmmod -v ldlm_extent ||
32190                 error "rmmod failed (may trigger a failure in a later test)"
32191 }
32192 run_test 842 "Measure ldlm_extent performance"
32193
32194 test_850() {
32195         local dir=$DIR/$tdir
32196         local file=$dir/$tfile
32197         local statsfile=$dir/all_job_stats.txt
32198
32199         test_mkdir -p $dir || error "failed to create dir $dir"
32200         echo "abcdefg" > $file || error "failed to create file $file"
32201
32202         # read job_stats in the living system
32203         lljobstat -n 1 ||
32204                 error "failed to run lljobstat on living system"
32205
32206         $LCTL get_param *.*.job_stats > $statsfile
32207         lljobstat --statsfile=$statsfile ||
32208                 error "failed to run lljobstat on file $statsfile"
32209 }
32210 run_test 850 "lljobstat can parse living and aggregated job_stats"
32211
32212 test_851() {
32213         local dir=$DIR/$tdir
32214         local file=$dir/f_test_851_$$
32215         local report=/tmp/report_test_851_$$
32216         local fanotify_prog=monitor_lustrefs
32217         local pid
32218
32219         test_mkdir $dir || error "failed to create dir $dir"
32220
32221         $fanotify_prog $DIR > $report &
32222         pid=$!
32223
32224         sleep 1
32225         if ! kill -0 $pid; then
32226                 error "failed to start $fanoify_prog"
32227         fi
32228
32229         stack_trap "kill $pid"
32230         stack_trap "rm -f $report"
32231
32232         echo "1234567890" > $file
32233         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32234                 error "fanotify did not report anything after 30 seconds"
32235         grep -a -E "open.*:$file:" $report ||
32236                 error "no open event for writing $file"
32237         grep -a -E "write.*:$file:" $report ||
32238                 error "no write event for writing $file"
32239         grep -a -E "close.*:$file:" $report ||
32240                 error "no close event for writing $file"
32241
32242         > $report
32243         cat $file
32244         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32245                 error "fanotify did not report anything after 30 seconds"
32246         grep -a -E "open.*:$file:" $report ||
32247                 error "no open event for reading $file"
32248         grep -a -E "read.*:$file:" $report ||
32249                 error "no write event for reading $file"
32250         grep -a -E "close.*:$file:" $report ||
32251                 error "no close event for reading $file"
32252 }
32253 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32254
32255 test_852() {
32256         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32257         (( $MDS1_VERSION >= $(version_code 2.15.61) )) ||
32258                 skip "Need MDS version at least 2.15.61 for intent mkdir"
32259
32260         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
32261
32262         save_lustre_params client "llite.*.intent_mkdir" > $save
32263         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
32264         $LCTL set_param llite.*.intent_mkdir=1
32265
32266         test_mkdir -p -c$MDSCOUNT $DIR/$tdir
32267         if [ $MDSCOUNT -ge 2 ]; then
32268                 $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir ||
32269                         error "set default dirstripe failed"
32270         fi
32271
32272         mkdir $DIR/$tdir/tdir || error "mkdir tdir failed"
32273         mkdir $DIR/$tdir/tdir/tfile || error "mkdir tdir/tfile failed"
32274         touch -d "2020-08-25 15:08" $DIR/$tdir/tdir/tfile ||
32275                 error "touch time failed"
32276         chown 0:0 $DIR/$tdir/tdir/tfile || error "chown 0:0 tdir/tfile failed"
32277         chmod 755 $DIR/$tdir/tdir/tfile || error "chmod 755 tdir/tfile failed"
32278 }
32279 run_test 852 "mkdir using intent lock for striped directory"
32280
32281 #
32282 # tests that do cleanup/setup should be run at the end
32283 #
32284
32285 test_900() {
32286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32287         local ls
32288
32289         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32290         $LCTL set_param fail_loc=0x903
32291
32292         cancel_lru_locks MGC
32293
32294         FAIL_ON_ERROR=true cleanup
32295         FAIL_ON_ERROR=true setup
32296 }
32297 run_test 900 "umount should not race with any mgc requeue thread"
32298
32299 # LUS-6253/LU-11185
32300 test_901() {
32301         local old
32302         local count
32303         local oldc
32304         local newc
32305         local olds
32306         local news
32307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32308
32309         # some get_param have a bug to handle dot in param name
32310         cancel_lru_locks MGC
32311         old=$(mount -t lustre | wc -l)
32312         # 1 config+sptlrpc
32313         # 2 params
32314         # 3 nodemap
32315         # 4 IR
32316         old=$((old * 4))
32317         oldc=0
32318         count=0
32319         while [ $old -ne $oldc ]; do
32320                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32321                 sleep 1
32322                 ((count++))
32323                 if [ $count -ge $TIMEOUT ]; then
32324                         error "too large timeout"
32325                 fi
32326         done
32327         umount_client $MOUNT || error "umount failed"
32328         mount_client $MOUNT || error "mount failed"
32329         cancel_lru_locks MGC
32330         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32331
32332         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32333
32334         return 0
32335 }
32336 run_test 901 "don't leak a mgc lock on client umount"
32337
32338 # LU-13377
32339 test_902() {
32340         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32341                 skip "client does not have LU-13377 fix"
32342         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32343         $LCTL set_param fail_loc=0x1415
32344         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32345         cancel_lru_locks osc
32346         rm -f $DIR/$tfile
32347 }
32348 run_test 902 "test short write doesn't hang lustre"
32349
32350 # LU-14711
32351 test_903() {
32352         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32353         echo "blah" > $DIR/${tfile}-2
32354         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32355         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32356         $LCTL set_param fail_loc=0x417 fail_val=20
32357
32358         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32359         sleep 1 # To start the destroy
32360         wait_destroy_complete 150 || error "Destroy taking too long"
32361         cat $DIR/$tfile > /dev/null || error "Evicted"
32362 }
32363 run_test 903 "Test long page discard does not cause evictions"
32364
32365 test_904() {
32366         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32367         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32368                 grep -q project || skip "skip project quota not supported"
32369
32370         local testfile="$DIR/$tdir/$tfile"
32371         local xattr="trusted.projid"
32372         local projid
32373         local mdts=$(comma_list $(mdts_nodes))
32374         local saved=$(do_facet mds1 $LCTL get_param -n \
32375                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32376
32377         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32378         stack_trap "do_nodes $mdts $LCTL set_param \
32379                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32380
32381         mkdir -p $DIR/$tdir
32382         touch $testfile
32383         #hide projid xattr on server
32384         $LFS project -p 1 $testfile ||
32385                 error "set $testfile project id failed"
32386         getfattr -m - $testfile | grep $xattr &&
32387                 error "do not show trusted.projid when disabled on server"
32388         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32389         #should be hidden when projid is 0
32390         $LFS project -p 0 $testfile ||
32391                 error "set $testfile project id failed"
32392         getfattr -m - $testfile | grep $xattr &&
32393                 error "do not show trusted.projid with project ID 0"
32394
32395         #still can getxattr explicitly
32396         projid=$(getfattr -n $xattr $testfile |
32397                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32398         [ $projid == "0" ] ||
32399                 error "projid expected 0 not $projid"
32400
32401         #set the projid via setxattr
32402         setfattr -n $xattr -v "1000" $testfile ||
32403                 error "setattr failed with $?"
32404         projid=($($LFS project $testfile))
32405         [ ${projid[0]} == "1000" ] ||
32406                 error "projid expected 1000 not $projid"
32407
32408         #check the new projid via getxattr
32409         $LFS project -p 1001 $testfile ||
32410                 error "set $testfile project id failed"
32411         getfattr -m - $testfile | grep $xattr ||
32412                 error "should show trusted.projid when project ID != 0"
32413         projid=$(getfattr -n $xattr $testfile |
32414                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32415         [ $projid == "1001" ] ||
32416                 error "projid expected 1001 not $projid"
32417
32418         #try to set invalid projid
32419         setfattr -n $xattr -v "4294967295" $testfile &&
32420                 error "set invalid projid should fail"
32421
32422         #remove the xattr means setting projid to 0
32423         setfattr -x $xattr $testfile ||
32424                 error "setfattr failed with $?"
32425         projid=($($LFS project $testfile))
32426         [ ${projid[0]} == "0" ] ||
32427                 error "projid expected 0 not $projid"
32428
32429         #should be hidden when parent has inherit flag and same projid
32430         $LFS project -srp 1002 $DIR/$tdir ||
32431                 error "set $tdir project id failed"
32432         getfattr -m - $testfile | grep $xattr &&
32433                 error "do not show trusted.projid with inherit flag"
32434
32435         #still can getxattr explicitly
32436         projid=$(getfattr -n $xattr $testfile |
32437                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32438         [ $projid == "1002" ] ||
32439                 error "projid expected 1002 not $projid"
32440 }
32441 run_test 904 "virtual project ID xattr"
32442
32443 # LU-8582
32444 test_905() {
32445         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32446                 skip "need OST version >= 2.15.50.220 for fail_loc"
32447
32448         remote_ost_nodsh && skip "remote OST with nodsh"
32449         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32450
32451         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32452
32453         #define OBD_FAIL_OST_OPCODE 0x253
32454         # OST_LADVISE = 21
32455         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32456         $LFS ladvise -a willread $DIR/$tfile &&
32457                 error "unexpected success of ladvise with fault injection"
32458         $LFS ladvise -a willread $DIR/$tfile |&
32459                 grep -q "Operation not supported"
32460         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32461 }
32462 run_test 905 "bad or new opcode should not stuck client"
32463
32464 test_906() {
32465         grep -q io_uring_setup /proc/kallsyms ||
32466                 skip "Client OS does not support io_uring I/O engine"
32467         io_uring_probe || skip "kernel does not support io_uring fully"
32468         which fio || skip_env "no fio installed"
32469         fio --enghelp | grep -q io_uring ||
32470                 skip_env "fio does not support io_uring I/O engine"
32471
32472         local file=$DIR/$tfile
32473         local ioengine="io_uring"
32474         local numjobs=2
32475         local size=50M
32476
32477         fio --name=seqwrite --ioengine=$ioengine        \
32478                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32479                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32480                 error "fio seqwrite $file failed"
32481
32482         fio --name=seqread --ioengine=$ioengine \
32483                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32484                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32485                 error "fio seqread $file failed"
32486
32487         rm -f $file || error "rm -f $file failed"
32488 }
32489 run_test 906 "Simple test for io_uring I/O engine via fio"
32490
32491 test_907() {
32492         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32493
32494         # set stripe size to max rpc size
32495         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32496         $LFS getstripe $DIR/$tfile
32497 #define OBD_FAIL_OST_EROFS               0x216
32498         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32499
32500         local bs=$((max_pages * PAGE_SIZE / 16))
32501
32502         # write full one stripe and one block
32503         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32504
32505         rm $DIR/$tfile || error "rm failed"
32506 }
32507 run_test 907 "write rpc error during unlink"
32508
32509 complete_test $SECONDS
32510 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32511 check_and_cleanup_lustre
32512 if [ "$I_MOUNTED" != "yes" ]; then
32513         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32514 fi
32515 exit_status