Whamcloud - gitweb
c2ec956b444b57e1c670b6181dc4c0add7eb10f4
[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 cl_user2
18728         local pid1
18729         local first_rec
18730         local last_rec=0
18731
18732         # Create a user
18733         changelog_register || error "first changelog_register failed"
18734
18735         cl_users=(${CL_USERS[mds1]})
18736         cl_user1="${cl_users[0]}"
18737
18738         # generate some changelog records to accumulate on MDT0
18739         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18740         first_rec=$(changelog_users $SINGLEMDS |
18741                         awk '/^current.index:/ { print $NF }')
18742         while (( last_rec < (( first_rec + 65000)) )); do
18743                 createmany -m $DIR/$tdir/$tfile 10000 ||
18744                         error "create $DIR/$tdir/$tfile failed"
18745
18746                 for i in $(seq 0 10000); do
18747                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18748                                 > /dev/null
18749                 done
18750
18751                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18752                         error "unlinkmany failed unlink"
18753                 last_rec=$(changelog_users $SINGLEMDS |
18754                         awk '/^current.index:/ { print $NF }')
18755                 echo last record $last_rec
18756                 (( last_rec == 0 )) && error "no changelog found"
18757         done
18758
18759 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18760         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18761
18762         __changelog_clear mds1 $cl_user1 0 &
18763         pid1=$!
18764         sleep 2
18765         __changelog_clear mds1 $cl_user1 0 ||
18766                 error "fail to cancel record for $cl_user1"
18767         wait $pid1
18768         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18769 }
18770 run_test 160n "Changelog destroy race"
18771
18772 test_160o() {
18773         local mdt="$(facet_svc $SINGLEMDS)"
18774
18775         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18776         remote_mds_nodsh && skip "remote MDS with nodsh"
18777         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18778                 skip "Need MDS version at least 2.14.52"
18779
18780         changelog_register --user test_160o -m unlnk+close+open ||
18781                 error "changelog_register failed"
18782
18783         do_facet $SINGLEMDS $LCTL --device $mdt \
18784                                 changelog_register -u "Tt3_-#" &&
18785                 error "bad symbols in name should fail"
18786
18787         do_facet $SINGLEMDS $LCTL --device $mdt \
18788                                 changelog_register -u test_160o &&
18789                 error "the same name registration should fail"
18790
18791         do_facet $SINGLEMDS $LCTL --device $mdt \
18792                         changelog_register -u test_160toolongname &&
18793                 error "too long name registration should fail"
18794
18795         changelog_chmask "MARK+HSM"
18796         lctl get_param mdd.*.changelog*mask
18797         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18798         changelog_users $SINGLEMDS | grep -q $cl_user ||
18799                 error "User $cl_user not found in changelog_users"
18800         #verify username
18801         echo $cl_user | grep -q test_160o ||
18802                 error "User $cl_user has no specific name 'test160o'"
18803
18804         # change something
18805         changelog_clear 0 || error "changelog_clear failed"
18806         # generate some changelog records to accumulate on MDT0
18807         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18808         touch $DIR/$tdir/$tfile                 # open 1
18809
18810         OPENS=$(changelog_dump | grep -c "OPEN")
18811         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18812
18813         # must be no MKDIR it wasn't set as user mask
18814         MKDIR=$(changelog_dump | grep -c "MKDIR")
18815         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18816
18817         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18818                                 mdd.$mdt.changelog_current_mask -n)
18819         # register maskless user
18820         changelog_register || error "changelog_register failed"
18821         # effective mask should be not changed because it is not minimal
18822         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18823                                 mdd.$mdt.changelog_current_mask -n)
18824         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18825         # set server mask to minimal value
18826         changelog_chmask "MARK"
18827         # check effective mask again, should be treated as DEFMASK now
18828         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18829                                 mdd.$mdt.changelog_current_mask -n)
18830         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18831
18832         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18833                 # set server mask back to some value
18834                 changelog_chmask "CLOSE,UNLNK"
18835                 # check effective mask again, should not remain as DEFMASK
18836                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18837                                 mdd.$mdt.changelog_current_mask -n)
18838                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18839         fi
18840
18841         do_facet $SINGLEMDS $LCTL --device $mdt \
18842                                 changelog_deregister -u test_160o ||
18843                 error "cannot deregister by name"
18844 }
18845 run_test 160o "changelog user name and mask"
18846
18847 test_160p() {
18848         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18849         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18850                 skip "Need MDS version at least 2.14.51"
18851         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18852         local cl_users
18853         local cl_user1
18854         local entry_count
18855
18856         # Create a user
18857         changelog_register || error "first changelog_register failed"
18858
18859         cl_users=(${CL_USERS[mds1]})
18860         cl_user1="${cl_users[0]}"
18861
18862         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18863         createmany -m $DIR/$tdir/$tfile 50 ||
18864                 error "create $DIR/$tdir/$tfile failed"
18865         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18866         rm -rf $DIR/$tdir
18867
18868         # check changelogs have been generated
18869         entry_count=$(changelog_dump | wc -l)
18870         ((entry_count != 0)) || error "no changelog entries found"
18871
18872         # remove changelog_users and check that orphan entries are removed
18873         stop mds1
18874         local dev=$(mdsdevname 1)
18875         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18876         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18877         entry_count=$(changelog_dump | wc -l)
18878         ((entry_count == 0)) ||
18879                 error "found $entry_count changelog entries, expected none"
18880 }
18881 run_test 160p "Changelog orphan cleanup with no users"
18882
18883 test_160q() {
18884         local mdt="$(facet_svc $SINGLEMDS)"
18885         local clu
18886
18887         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18888         remote_mds_nodsh && skip "remote MDS with nodsh"
18889         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18890                 skip "Need MDS version at least 2.14.54"
18891
18892         # set server mask to minimal value like server init does
18893         changelog_chmask "MARK"
18894         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18895                 error "changelog_register failed"
18896         # check effective mask again, should be treated as DEFMASK now
18897         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18898                                 mdd.$mdt.changelog_current_mask -n)
18899         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18900                 error "changelog_deregister failed"
18901         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18902 }
18903 run_test 160q "changelog effective mask is DEFMASK if not set"
18904
18905 test_160s() {
18906         remote_mds_nodsh && skip "remote MDS with nodsh"
18907         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18908                 skip "Need MDS version at least 2.14.55"
18909
18910         local mdts=$(comma_list $(mdts_nodes))
18911
18912         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18913         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18914                                        fail_val=$((24 * 3600 * 10))
18915
18916         # Create a user which is 10 days old
18917         changelog_register || error "first changelog_register failed"
18918         local cl_users
18919         declare -A cl_user1
18920         local i
18921
18922         # generate some changelog records to accumulate on each MDT
18923         # use all_char because created files should be evenly distributed
18924         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18925                 error "test_mkdir $tdir failed"
18926         for ((i = 0; i < MDSCOUNT; i++)); do
18927                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18928                         error "create $DIR/$tdir/d$i.1 failed"
18929         done
18930
18931         # check changelogs have been generated
18932         local nbcl=$(changelog_dump | wc -l)
18933         (( nbcl > 0 )) || error "no changelogs found"
18934
18935         # reduce the max_idle_indexes value to make sure we exceed it
18936         for param in "changelog_max_idle_indexes=2097446912" \
18937                      "changelog_max_idle_time=2592000" \
18938                      "changelog_gc=1" \
18939                      "changelog_min_gc_interval=2"; do
18940                 local MDT0=$(facet_svc $SINGLEMDS)
18941                 local var="${param%=*}"
18942                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18943
18944                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18945                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18946                         error "unable to set mdd.*.$param"
18947         done
18948
18949         local start=$SECONDS
18950         for i in $(seq $MDSCOUNT); do
18951                 cl_users=(${CL_USERS[mds$i]})
18952                 cl_user1[mds$i]="${cl_users[0]}"
18953
18954                 [[ -n "${cl_user1[mds$i]}" ]] ||
18955                         error "mds$i: no user registered"
18956         done
18957
18958         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18959         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18960
18961         # ensure we are past the previous changelog_min_gc_interval set above
18962         local sleep2=$((start + 2 - SECONDS))
18963         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18964
18965         # Generate one more changelog to trigger GC
18966         for ((i = 0; i < MDSCOUNT; i++)); do
18967                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18968                         error "create $DIR/$tdir/d$i.3 failed"
18969         done
18970
18971         # ensure gc thread is done
18972         for node in $(mdts_nodes); do
18973                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18974                         error "$node: GC-thread not done"
18975         done
18976
18977         do_nodes $mdts $LCTL set_param fail_loc=0
18978
18979         for (( i = 1; i <= MDSCOUNT; i++ )); do
18980                 # check cl_user1 is purged
18981                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18982                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18983         done
18984         return 0
18985 }
18986 run_test 160s "changelog garbage collect on idle records * time"
18987
18988 test_160t() {
18989         remote_mds_nodsh && skip "remote MDS with nodsh"
18990         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18991                 skip "Need MDS version at least 2.15.50"
18992
18993         local MDT0=$(facet_svc $SINGLEMDS)
18994         local cl_users
18995         local cl_user1
18996         local cl_user2
18997         local start
18998
18999         changelog_register --user user1 -m all ||
19000                 error "user1 failed to register"
19001
19002         mkdir_on_mdt0 $DIR/$tdir
19003         # create default overstripe to maximize changelog size
19004         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
19005         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
19006         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
19007
19008         # user2 consumes less records so less space
19009         changelog_register --user user2 || error "user2 failed to register"
19010         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
19011         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
19012
19013         # check changelogs have been generated
19014         local nbcl=$(changelog_dump | wc -l)
19015         (( nbcl > 0 )) || error "no changelogs found"
19016
19017         # reduce the changelog_min_gc_interval to force check
19018         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
19019                 local var="${param%=*}"
19020                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
19021
19022                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
19023                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
19024                         error "unable to set mdd.*.$param"
19025         done
19026
19027         start=$SECONDS
19028         cl_users=(${CL_USERS[mds1]})
19029         cl_user1="${cl_users[0]}"
19030         cl_user2="${cl_users[1]}"
19031
19032         [[ -n $cl_user1 ]] ||
19033                 error "mds1: user #1 isn't registered"
19034         [[ -n $cl_user2 ]] ||
19035                 error "mds1: user #2 isn't registered"
19036
19037         # ensure we are past the previous changelog_min_gc_interval set above
19038         local sleep2=$((start + 2 - SECONDS))
19039         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
19040
19041         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
19042         do_facet mds1 $LCTL set_param fail_loc=0x018c \
19043                         fail_val=$(((llog_size1 + llog_size2) / 2))
19044
19045         # Generate more changelog to trigger GC
19046         createmany -o $DIR/$tdir/u3_ 4 ||
19047                 error "create failed for more files"
19048
19049         # ensure gc thread is done
19050         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
19051                 error "mds1: GC-thread not done"
19052
19053         do_facet mds1 $LCTL set_param fail_loc=0
19054
19055         # check cl_user1 is purged
19056         changelog_users mds1 | grep -q "$cl_user1" &&
19057                 error "User $cl_user1 is registered"
19058         # check cl_user2 is not purged
19059         changelog_users mds1 | grep -q "$cl_user2" ||
19060                 error "User $cl_user2 is not registered"
19061 }
19062 run_test 160t "changelog garbage collect on lack of space"
19063
19064 test_160u() { # LU-17400
19065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19066         remote_mds_nodsh && skip "remote MDS with nodsh"
19067         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
19068                 skip "Need MDS version at least 2.2.0"
19069
19070         cd $DIR || error "cd $DIR failed"
19071
19072         # ensure changelog has a clean view if tests are run multiple times
19073         [ -d rename ] && rm -rf rename
19074
19075         changelog_register || error "changelog_register failed"
19076         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
19077
19078         changelog_users $SINGLEMDS | grep -q $cl_user ||
19079                 error "User '$cl_user' not found in changelog_users"
19080
19081         local longname1=$(str_repeat a 255)
19082
19083         echo "creating simple directory tree"
19084         mkdir -p rename/a || error "create of simple directory tree failed"
19085         echo "creating rename/hw file"
19086         echo "hello world" > rename/hw || error "create of rename/hw failed"
19087         echo "creating very long named file"
19088         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
19089         echo "move rename/hw to rename/a/a.hw"
19090         mv rename/hw rename/a/a.hw || error "mv failed"
19091
19092         RENME=($(changelog_dump | grep "RENME"))
19093         #declare -p RENME # for debugging captured value with indexes
19094
19095         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
19096                 error "changelog rename record type name/sname error"
19097 }
19098 run_test 160u "changelog rename record type name and sname strings are correct"
19099
19100 test_161a() {
19101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19102
19103         test_mkdir -c1 $DIR/$tdir
19104         cp /etc/hosts $DIR/$tdir/$tfile
19105         test_mkdir -c1 $DIR/$tdir/foo1
19106         test_mkdir -c1 $DIR/$tdir/foo2
19107         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
19108         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
19109         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
19110         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
19111         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
19112         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19113                 $LFS fid2path $DIR $FID
19114                 error "bad link ea"
19115         fi
19116         # middle
19117         rm $DIR/$tdir/foo2/zachary
19118         # last
19119         rm $DIR/$tdir/foo2/thor
19120         # first
19121         rm $DIR/$tdir/$tfile
19122         # rename
19123         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
19124         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
19125                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
19126         rm $DIR/$tdir/foo2/maggie
19127
19128         # overflow the EA
19129         local longname=$tfile.avg_len_is_thirty_two_
19130         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
19131                 error_noexit 'failed to unlink many hardlinks'" EXIT
19132         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
19133                 error "failed to hardlink many files"
19134         links=$($LFS fid2path $DIR $FID | wc -l)
19135         echo -n "${links}/1000 links in link EA"
19136         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
19137 }
19138 run_test 161a "link ea sanity"
19139
19140 test_161b() {
19141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19142         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
19143
19144         local MDTIDX=1
19145         local remote_dir=$DIR/$tdir/remote_dir
19146
19147         mkdir -p $DIR/$tdir
19148         $LFS mkdir -i $MDTIDX $remote_dir ||
19149                 error "create remote directory failed"
19150
19151         cp /etc/hosts $remote_dir/$tfile
19152         mkdir -p $remote_dir/foo1
19153         mkdir -p $remote_dir/foo2
19154         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19155         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19156         ln $remote_dir/$tfile $remote_dir/foo1/luna
19157         ln $remote_dir/$tfile $remote_dir/foo2/thor
19158
19159         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19160                      tr -d ']')
19161         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19162                 $LFS fid2path $DIR $FID
19163                 error "bad link ea"
19164         fi
19165         # middle
19166         rm $remote_dir/foo2/zachary
19167         # last
19168         rm $remote_dir/foo2/thor
19169         # first
19170         rm $remote_dir/$tfile
19171         # rename
19172         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19173         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19174         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19175                 $LFS fid2path $DIR $FID
19176                 error "bad link rename"
19177         fi
19178         rm $remote_dir/foo2/maggie
19179
19180         # overflow the EA
19181         local longname=filename_avg_len_is_thirty_two_
19182         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19183                 error "failed to hardlink many files"
19184         links=$($LFS fid2path $DIR $FID | wc -l)
19185         echo -n "${links}/1000 links in link EA"
19186         [[ ${links} -gt 60 ]] ||
19187                 error "expected at least 60 links in link EA"
19188         unlinkmany $remote_dir/foo2/$longname 1000 ||
19189         error "failed to unlink many hardlinks"
19190 }
19191 run_test 161b "link ea sanity under remote directory"
19192
19193 test_161c() {
19194         remote_mds_nodsh && skip "remote MDS with nodsh"
19195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19196         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19197                 skip "Need MDS version at least 2.1.5"
19198
19199         # define CLF_RENAME_LAST 0x0001
19200         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19201         changelog_register || error "changelog_register failed"
19202
19203         rm -rf $DIR/$tdir
19204         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19205         touch $DIR/$tdir/foo_161c
19206         touch $DIR/$tdir/bar_161c
19207         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19208         changelog_dump | grep RENME | tail -n 5
19209         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19210         changelog_clear 0 || error "changelog_clear failed"
19211         if [ x$flags != "x0x1" ]; then
19212                 error "flag $flags is not 0x1"
19213         fi
19214
19215         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19216         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19217         touch $DIR/$tdir/foo_161c
19218         touch $DIR/$tdir/bar_161c
19219         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19220         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19221         changelog_dump | grep RENME | tail -n 5
19222         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19223         changelog_clear 0 || error "changelog_clear failed"
19224         if [ x$flags != "x0x0" ]; then
19225                 error "flag $flags is not 0x0"
19226         fi
19227         echo "rename overwrite a target having nlink > 1," \
19228                 "changelog record has flags of $flags"
19229
19230         # rename doesn't overwrite a target (changelog flag 0x0)
19231         touch $DIR/$tdir/foo_161c
19232         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19233         changelog_dump | grep RENME | tail -n 5
19234         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19235         changelog_clear 0 || error "changelog_clear failed"
19236         if [ x$flags != "x0x0" ]; then
19237                 error "flag $flags is not 0x0"
19238         fi
19239         echo "rename doesn't overwrite a target," \
19240                 "changelog record has flags of $flags"
19241
19242         # define CLF_UNLINK_LAST 0x0001
19243         # unlink a file having nlink = 1 (changelog flag 0x1)
19244         rm -f $DIR/$tdir/foo2_161c
19245         changelog_dump | grep UNLNK | tail -n 5
19246         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19247         changelog_clear 0 || error "changelog_clear failed"
19248         if [ x$flags != "x0x1" ]; then
19249                 error "flag $flags is not 0x1"
19250         fi
19251         echo "unlink a file having nlink = 1," \
19252                 "changelog record has flags of $flags"
19253
19254         # unlink a file having nlink > 1 (changelog flag 0x0)
19255         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19256         rm -f $DIR/$tdir/foobar_161c
19257         changelog_dump | grep UNLNK | tail -n 5
19258         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19259         changelog_clear 0 || error "changelog_clear failed"
19260         if [ x$flags != "x0x0" ]; then
19261                 error "flag $flags is not 0x0"
19262         fi
19263         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19264 }
19265 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19266
19267 test_161d() {
19268         remote_mds_nodsh && skip "remote MDS with nodsh"
19269         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19270
19271         local pid
19272         local fid
19273
19274         changelog_register || error "changelog_register failed"
19275
19276         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19277         # interfer with $MOUNT/.lustre/fid/ access
19278         mkdir $DIR/$tdir
19279         [[ $? -eq 0 ]] || error "mkdir failed"
19280
19281         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19282         $LCTL set_param fail_loc=0x8000140c
19283         # 5s pause
19284         $LCTL set_param fail_val=5
19285
19286         # create file
19287         echo foofoo > $DIR/$tdir/$tfile &
19288         pid=$!
19289
19290         # wait for create to be delayed
19291         sleep 2
19292
19293         ps -p $pid
19294         [[ $? -eq 0 ]] || error "create should be blocked"
19295
19296         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19297         stack_trap "rm -f $tempfile"
19298         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19299         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19300         # some delay may occur during ChangeLog publishing and file read just
19301         # above, that could allow file write to happen finally
19302         [[ -s $tempfile ]] && echo "file should be empty"
19303
19304         $LCTL set_param fail_loc=0
19305
19306         wait $pid
19307         [[ $? -eq 0 ]] || error "create failed"
19308 }
19309 run_test 161d "create with concurrent .lustre/fid access"
19310
19311 check_path() {
19312         local expected="$1"
19313         shift
19314         local fid="$2"
19315
19316         local path
19317         path=$($LFS fid2path "$@")
19318         local rc=$?
19319
19320         if [ $rc -ne 0 ]; then
19321                 error "path looked up of '$expected' failed: rc=$rc"
19322         elif [ "$path" != "$expected" ]; then
19323                 error "path looked up '$path' instead of '$expected'"
19324         else
19325                 echo "FID '$fid' resolves to path '$path' as expected"
19326         fi
19327 }
19328
19329 test_162a() { # was test_162
19330         test_mkdir -p -c1 $DIR/$tdir/d2
19331         touch $DIR/$tdir/d2/$tfile
19332         touch $DIR/$tdir/d2/x1
19333         touch $DIR/$tdir/d2/x2
19334         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19335         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19336         # regular file
19337         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19338         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19339
19340         # softlink
19341         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19342         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19343         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19344
19345         # softlink to wrong file
19346         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19347         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19348         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19349
19350         # hardlink
19351         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19352         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19353         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19354         # fid2path dir/fsname should both work
19355         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19356         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19357
19358         # hardlink count: check that there are 2 links
19359         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19360         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19361
19362         # hardlink indexing: remove the first link
19363         rm $DIR/$tdir/d2/p/q/r/hlink
19364         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19365 }
19366 run_test 162a "path lookup sanity"
19367
19368 test_162b() {
19369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19371
19372         mkdir $DIR/$tdir
19373         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19374                                 error "create striped dir failed"
19375
19376         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19377                                         tail -n 1 | awk '{print $2}')
19378         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19379
19380         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19381         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19382
19383         # regular file
19384         for ((i=0;i<5;i++)); do
19385                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19386                         error "get fid for f$i failed"
19387                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19388
19389                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19390                         error "get fid for d$i failed"
19391                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19392         done
19393
19394         return 0
19395 }
19396 run_test 162b "striped directory path lookup sanity"
19397
19398 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19399 test_162c() {
19400         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19401                 skip "Need MDS version at least 2.7.51"
19402
19403         local lpath=$tdir.local
19404         local rpath=$tdir.remote
19405
19406         test_mkdir $DIR/$lpath
19407         test_mkdir $DIR/$rpath
19408
19409         for ((i = 0; i <= 101; i++)); do
19410                 lpath="$lpath/$i"
19411                 mkdir $DIR/$lpath
19412                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19413                         error "get fid for local directory $DIR/$lpath failed"
19414                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19415
19416                 rpath="$rpath/$i"
19417                 test_mkdir $DIR/$rpath
19418                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19419                         error "get fid for remote directory $DIR/$rpath failed"
19420                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19421         done
19422
19423         return 0
19424 }
19425 run_test 162c "fid2path works with paths 100 or more directories deep"
19426
19427 oalr_event_count() {
19428         local event="${1}"
19429         local trace="${2}"
19430
19431         awk -v name="${FSNAME}-OST0000" \
19432             -v event="${event}" \
19433             '$1 == "TRACE" && $2 == event && $3 == name' \
19434             "${trace}" |
19435         wc -l
19436 }
19437
19438 oalr_expect_event_count() {
19439         local event="${1}"
19440         local trace="${2}"
19441         local expect="${3}"
19442         local count
19443
19444         count=$(oalr_event_count "${event}" "${trace}")
19445         if ((count == expect)); then
19446                 return 0
19447         fi
19448
19449         error_noexit "${event} event count was '${count}', expected ${expect}"
19450         cat "${trace}" >&2
19451         exit 1
19452 }
19453
19454 cleanup_165() {
19455         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19456         stop ost1
19457         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19458 }
19459
19460 setup_165() {
19461         sync # Flush previous IOs so we can count log entries.
19462         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19463         stack_trap cleanup_165 EXIT
19464 }
19465
19466 test_165a() {
19467         local trace="/tmp/${tfile}.trace"
19468         local rc
19469         local count
19470
19471         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19472                 skip "OFD access log unsupported"
19473
19474         setup_165
19475         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19476         sleep 5
19477
19478         do_facet ost1 ofd_access_log_reader --list
19479         stop ost1
19480
19481         do_facet ost1 killall -TERM ofd_access_log_reader
19482         wait
19483         rc=$?
19484
19485         if ((rc != 0)); then
19486                 error "ofd_access_log_reader exited with rc = '${rc}'"
19487         fi
19488
19489         # Parse trace file for discovery events:
19490         oalr_expect_event_count alr_log_add "${trace}" 1
19491         oalr_expect_event_count alr_log_eof "${trace}" 1
19492         oalr_expect_event_count alr_log_free "${trace}" 1
19493 }
19494 run_test 165a "ofd access log discovery"
19495
19496 test_165b() {
19497         local trace="/tmp/${tfile}.trace"
19498         local file="${DIR}/${tfile}"
19499         local pfid1
19500         local pfid2
19501         local -a entry
19502         local rc
19503         local count
19504         local size
19505         local flags
19506
19507         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19508                 skip "OFD access log unsupported"
19509
19510         setup_165
19511         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19512         sleep 5
19513
19514         do_facet ost1 ofd_access_log_reader --list
19515
19516         lfs setstripe -c 1 -i 0 "${file}"
19517         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19518                 error "cannot create '${file}'"
19519
19520         sleep 5
19521         do_facet ost1 killall -TERM ofd_access_log_reader
19522         wait
19523         rc=$?
19524
19525         if ((rc != 0)); then
19526                 error "ofd_access_log_reader exited with rc = '${rc}'"
19527         fi
19528
19529         oalr_expect_event_count alr_log_entry "${trace}" 1
19530
19531         pfid1=$($LFS path2fid "${file}")
19532
19533         # 1     2             3   4    5     6   7    8    9     10
19534         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19535         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19536
19537         echo "entry = '${entry[*]}'" >&2
19538
19539         pfid2=${entry[4]}
19540         if [[ "${pfid1}" != "${pfid2}" ]]; then
19541                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19542         fi
19543
19544         size=${entry[8]}
19545         if ((size != 1048576)); then
19546                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19547         fi
19548
19549         flags=${entry[10]}
19550         if [[ "${flags}" != "w" ]]; then
19551                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19552         fi
19553
19554         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19555         sleep 5
19556
19557         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19558                 error "cannot read '${file}'"
19559         sleep 5
19560
19561         do_facet ost1 killall -TERM ofd_access_log_reader
19562         wait
19563         rc=$?
19564
19565         if ((rc != 0)); then
19566                 error "ofd_access_log_reader exited with rc = '${rc}'"
19567         fi
19568
19569         oalr_expect_event_count alr_log_entry "${trace}" 1
19570
19571         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19572         echo "entry = '${entry[*]}'" >&2
19573
19574         pfid2=${entry[4]}
19575         if [[ "${pfid1}" != "${pfid2}" ]]; then
19576                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19577         fi
19578
19579         size=${entry[8]}
19580         if ((size != 524288)); then
19581                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19582         fi
19583
19584         flags=${entry[10]}
19585         if [[ "${flags}" != "r" ]]; then
19586                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19587         fi
19588 }
19589 run_test 165b "ofd access log entries are produced and consumed"
19590
19591 test_165c() {
19592         local trace="/tmp/${tfile}.trace"
19593         local file="${DIR}/${tdir}/${tfile}"
19594
19595         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19596                 skip "OFD access log unsupported"
19597
19598         test_mkdir "${DIR}/${tdir}"
19599
19600         setup_165
19601         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19602         sleep 5
19603
19604         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19605
19606         # 4096 / 64 = 64. Create twice as many entries.
19607         for ((i = 0; i < 128; i++)); do
19608                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19609                         error "cannot create file"
19610         done
19611
19612         sync
19613
19614         do_facet ost1 killall -TERM ofd_access_log_reader
19615         wait
19616         rc=$?
19617         if ((rc != 0)); then
19618                 error "ofd_access_log_reader exited with rc = '${rc}'"
19619         fi
19620
19621         unlinkmany  "${file}-%d" 128
19622 }
19623 run_test 165c "full ofd access logs do not block IOs"
19624
19625 oal_get_read_count() {
19626         local stats="$1"
19627
19628         # STATS lustre-OST0001 alr_read_count 1
19629
19630         do_facet ost1 cat "${stats}" |
19631         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19632              END { print count; }'
19633 }
19634
19635 oal_expect_read_count() {
19636         local stats="$1"
19637         local count
19638         local expect="$2"
19639
19640         # Ask ofd_access_log_reader to write stats.
19641         do_facet ost1 killall -USR1 ofd_access_log_reader
19642
19643         # Allow some time for things to happen.
19644         sleep 1
19645
19646         count=$(oal_get_read_count "${stats}")
19647         if ((count == expect)); then
19648                 return 0
19649         fi
19650
19651         error_noexit "bad read count, got ${count}, expected ${expect}"
19652         do_facet ost1 cat "${stats}" >&2
19653         exit 1
19654 }
19655
19656 test_165d() {
19657         local stats="/tmp/${tfile}.stats"
19658         local file="${DIR}/${tdir}/${tfile}"
19659         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19660
19661         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19662                 skip "OFD access log unsupported"
19663
19664         test_mkdir "${DIR}/${tdir}"
19665
19666         setup_165
19667         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19668         sleep 5
19669
19670         lfs setstripe -c 1 -i 0 "${file}"
19671
19672         do_facet ost1 lctl set_param "${param}=rw"
19673         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19674                 error "cannot create '${file}'"
19675         oal_expect_read_count "${stats}" 1
19676
19677         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19678                 error "cannot read '${file}'"
19679         oal_expect_read_count "${stats}" 2
19680
19681         do_facet ost1 lctl set_param "${param}=r"
19682         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19683                 error "cannot create '${file}'"
19684         oal_expect_read_count "${stats}" 2
19685
19686         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19687                 error "cannot read '${file}'"
19688         oal_expect_read_count "${stats}" 3
19689
19690         do_facet ost1 lctl set_param "${param}=w"
19691         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19692                 error "cannot create '${file}'"
19693         oal_expect_read_count "${stats}" 4
19694
19695         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19696                 error "cannot read '${file}'"
19697         oal_expect_read_count "${stats}" 4
19698
19699         do_facet ost1 lctl set_param "${param}=0"
19700         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19701                 error "cannot create '${file}'"
19702         oal_expect_read_count "${stats}" 4
19703
19704         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19705                 error "cannot read '${file}'"
19706         oal_expect_read_count "${stats}" 4
19707
19708         do_facet ost1 killall -TERM ofd_access_log_reader
19709         wait
19710         rc=$?
19711         if ((rc != 0)); then
19712                 error "ofd_access_log_reader exited with rc = '${rc}'"
19713         fi
19714 }
19715 run_test 165d "ofd_access_log mask works"
19716
19717 test_165e() {
19718         local stats="/tmp/${tfile}.stats"
19719         local file0="${DIR}/${tdir}-0/${tfile}"
19720         local file1="${DIR}/${tdir}-1/${tfile}"
19721
19722         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19723                 skip "OFD access log unsupported"
19724
19725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19726
19727         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19728         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19729
19730         lfs setstripe -c 1 -i 0 "${file0}"
19731         lfs setstripe -c 1 -i 0 "${file1}"
19732
19733         setup_165
19734         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19735         sleep 5
19736
19737         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19738                 error "cannot create '${file0}'"
19739         sync
19740         oal_expect_read_count "${stats}" 0
19741
19742         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19743                 error "cannot create '${file1}'"
19744         sync
19745         oal_expect_read_count "${stats}" 1
19746
19747         do_facet ost1 killall -TERM ofd_access_log_reader
19748         wait
19749         rc=$?
19750         if ((rc != 0)); then
19751                 error "ofd_access_log_reader exited with rc = '${rc}'"
19752         fi
19753 }
19754 run_test 165e "ofd_access_log MDT index filter works"
19755
19756 test_165f() {
19757         local trace="/tmp/${tfile}.trace"
19758         local rc
19759         local count
19760
19761         setup_165
19762         do_facet ost1 timeout 60 ofd_access_log_reader \
19763                 --exit-on-close --debug=- --trace=- > "${trace}" &
19764         sleep 5
19765         stop ost1
19766
19767         wait
19768         rc=$?
19769
19770         if ((rc != 0)); then
19771                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19772                 cat "${trace}"
19773                 exit 1
19774         fi
19775 }
19776 run_test 165f "ofd_access_log_reader --exit-on-close works"
19777
19778 test_169() {
19779         # do directio so as not to populate the page cache
19780         log "creating a 10 Mb file"
19781         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19782                 error "multiop failed while creating a file"
19783         log "starting reads"
19784         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19785         log "truncating the file"
19786         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19787                 error "multiop failed while truncating the file"
19788         log "killing dd"
19789         kill %+ || true # reads might have finished
19790         echo "wait until dd is finished"
19791         wait
19792         log "removing the temporary file"
19793         rm -rf $DIR/$tfile || error "tmp file removal failed"
19794 }
19795 run_test 169 "parallel read and truncate should not deadlock"
19796
19797 test_170() {
19798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19799
19800         $LCTL clear     # bug 18514
19801         $LCTL debug_daemon start $TMP/${tfile}_log_good
19802         touch $DIR/$tfile
19803         $LCTL debug_daemon stop
19804         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19805                 error "sed failed to read log_good"
19806
19807         $LCTL debug_daemon start $TMP/${tfile}_log_good
19808         rm -rf $DIR/$tfile
19809         $LCTL debug_daemon stop
19810
19811         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19812                error "lctl df log_bad failed"
19813
19814         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19815         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19816
19817         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19818         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19819
19820         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19821                 error "bad_line good_line1 good_line2 are empty"
19822
19823         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19824         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19825         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19826
19827         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19828         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19829         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19830
19831         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19832                 error "bad_line_new good_line_new are empty"
19833
19834         local expected_good=$((good_line1 + good_line2*2))
19835
19836         rm -f $TMP/${tfile}*
19837         # LU-231, short malformed line may not be counted into bad lines
19838         if [ $bad_line -ne $bad_line_new ] &&
19839                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19840                 error "expected $bad_line bad lines, but got $bad_line_new"
19841                 return 1
19842         fi
19843
19844         if [ $expected_good -ne $good_line_new ]; then
19845                 error "expected $expected_good good lines, but got $good_line_new"
19846                 return 2
19847         fi
19848         true
19849 }
19850 run_test 170 "test lctl df to handle corrupted log ====================="
19851
19852 test_171() { # bug20592
19853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19854
19855         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19856         $LCTL set_param fail_loc=0x50e
19857         $LCTL set_param fail_val=3000
19858         multiop_bg_pause $DIR/$tfile O_s || true
19859         local MULTIPID=$!
19860         kill -USR1 $MULTIPID
19861         # cause log dump
19862         sleep 3
19863         wait $MULTIPID
19864         if dmesg | grep "recursive fault"; then
19865                 error "caught a recursive fault"
19866         fi
19867         $LCTL set_param fail_loc=0
19868         true
19869 }
19870 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19871
19872 test_172() {
19873
19874         #define OBD_FAIL_OBD_CLEANUP  0x60e
19875         $LCTL set_param fail_loc=0x60e
19876         umount $MOUNT || error "umount $MOUNT failed"
19877         stack_trap "mount_client $MOUNT"
19878
19879         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19880                 error "no client OBDs are remained"
19881
19882         $LCTL dl | while read devno state type name foo; do
19883                 case $type in
19884                 lov|osc|lmv|mdc)
19885                         $LCTL --device $name cleanup
19886                         $LCTL --device $name detach
19887                         ;;
19888                 *)
19889                         # skip server devices
19890                         ;;
19891                 esac
19892         done
19893
19894         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19895                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19896                 error "some client OBDs are still remained"
19897         fi
19898
19899 }
19900 run_test 172 "manual device removal with lctl cleanup/detach ======"
19901
19902 # it would be good to share it with obdfilter-survey/iokit-libecho code
19903 setup_obdecho_osc () {
19904         local rc=0
19905         local ost_nid=$1
19906         local obdfilter_name=$2
19907         echo "Creating new osc for $obdfilter_name on $ost_nid"
19908         # make sure we can find loopback nid
19909         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19910
19911         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19912                            ${obdfilter_name}_osc_UUID || rc=2; }
19913         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19914                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19915         return $rc
19916 }
19917
19918 cleanup_obdecho_osc () {
19919         local obdfilter_name=$1
19920         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19921         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19922         return 0
19923 }
19924
19925 obdecho_test() {
19926         local OBD=$1
19927         local node=$2
19928         local pages=${3:-64}
19929         local rc=0
19930         local id
19931
19932         local count=10
19933         local obd_size=$(get_obd_size $node $OBD)
19934         local page_size=$(get_page_size $node)
19935         if [[ -n "$obd_size" ]]; then
19936                 local new_count=$((obd_size / (pages * page_size / 1024)))
19937                 [[ $new_count -ge $count ]] || count=$new_count
19938         fi
19939
19940         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19941         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19942                            rc=2; }
19943         if [ $rc -eq 0 ]; then
19944             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19945             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19946         fi
19947         echo "New object id is $id"
19948         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19949                            rc=4; }
19950         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19951                            "test_brw $count w v $pages $id" || rc=4; }
19952         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19953                            rc=4; }
19954         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19955                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19956         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19957                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19958         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19959         return $rc
19960 }
19961
19962 test_180a() {
19963         skip "obdecho on osc is no longer supported"
19964 }
19965 run_test 180a "test obdecho on osc"
19966
19967 test_180b() {
19968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19969         remote_ost_nodsh && skip "remote OST with nodsh"
19970
19971         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19972                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19973                 error "failed to load module obdecho"
19974
19975         local target=$(do_facet ost1 $LCTL dl |
19976                        awk '/obdfilter/ { print $4; exit; }')
19977
19978         if [ -n "$target" ]; then
19979                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19980         else
19981                 do_facet ost1 $LCTL dl
19982                 error "there is no obdfilter target on ost1"
19983         fi
19984 }
19985 run_test 180b "test obdecho directly on obdfilter"
19986
19987 test_180c() { # LU-2598
19988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19989         remote_ost_nodsh && skip "remote OST with nodsh"
19990         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19991                 skip "Need MDS version at least 2.4.0"
19992
19993         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19994                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19995                 error "failed to load module obdecho"
19996
19997         local target=$(do_facet ost1 $LCTL dl |
19998                        awk '/obdfilter/ { print $4; exit; }')
19999
20000         if [ -n "$target" ]; then
20001                 local pages=16384 # 64MB bulk I/O RPC size
20002
20003                 obdecho_test "$target" ost1 "$pages" ||
20004                         error "obdecho_test with pages=$pages failed with $?"
20005         else
20006                 do_facet ost1 $LCTL dl
20007                 error "there is no obdfilter target on ost1"
20008         fi
20009 }
20010 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
20011
20012 test_181() { # bug 22177
20013         test_mkdir $DIR/$tdir
20014         # create enough files to index the directory
20015         createmany -o $DIR/$tdir/foobar 4000
20016         # print attributes for debug purpose
20017         lsattr -d .
20018         # open dir
20019         multiop_bg_pause $DIR/$tdir D_Sc || return 1
20020         MULTIPID=$!
20021         # remove the files & current working dir
20022         unlinkmany $DIR/$tdir/foobar 4000
20023         rmdir $DIR/$tdir
20024         kill -USR1 $MULTIPID
20025         wait $MULTIPID
20026         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
20027         return 0
20028 }
20029 run_test 181 "Test open-unlinked dir ========================"
20030
20031 test_182a() {
20032         local fcount=1000
20033         local tcount=10
20034
20035         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20036
20037         $LCTL set_param mdc.*.rpc_stats=clear
20038
20039         for (( i = 0; i < $tcount; i++ )) ; do
20040                 mkdir $DIR/$tdir/$i
20041         done
20042
20043         for (( i = 0; i < $tcount; i++ )) ; do
20044                 createmany -o $DIR/$tdir/$i/f- $fcount &
20045         done
20046         wait
20047
20048         for (( i = 0; i < $tcount; i++ )) ; do
20049                 unlinkmany $DIR/$tdir/$i/f- $fcount &
20050         done
20051         wait
20052
20053         $LCTL get_param mdc.*.rpc_stats
20054
20055         rm -rf $DIR/$tdir
20056 }
20057 run_test 182a "Test parallel modify metadata operations from mdc"
20058
20059 test_182b() {
20060         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20061         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20062         local dcount=1000
20063         local tcount=10
20064         local stime
20065         local etime
20066         local delta
20067
20068         do_facet mds1 $LCTL list_param \
20069                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
20070                 skip "MDS lacks parallel RPC handling"
20071
20072         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20073
20074         rpc_count=$(do_facet mds1 $LCTL get_param -n \
20075                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
20076
20077         stime=$(date +%s)
20078         createmany -i 0 -d $DIR/$tdir/t- $tcount
20079
20080         for (( i = 0; i < $tcount; i++ )) ; do
20081                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20082         done
20083         wait
20084         etime=$(date +%s)
20085         delta=$((etime - stime))
20086         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
20087
20088         stime=$(date +%s)
20089         for (( i = 0; i < $tcount; i++ )) ; do
20090                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
20091         done
20092         wait
20093         etime=$(date +%s)
20094         delta=$((etime - stime))
20095         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
20096
20097         rm -rf $DIR/$tdir
20098
20099         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20100
20101         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
20102
20103         stime=$(date +%s)
20104         createmany -i 0 -d $DIR/$tdir/t- $tcount
20105
20106         for (( i = 0; i < $tcount; i++ )) ; do
20107                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20108         done
20109         wait
20110         etime=$(date +%s)
20111         delta=$((etime - stime))
20112         echo "Time for file creation $delta sec for 1 RPC sent at a time"
20113
20114         stime=$(date +%s)
20115         for (( i = 0; i < $tcount; i++ )) ; do
20116                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
20117         done
20118         wait
20119         etime=$(date +%s)
20120         delta=$((etime - stime))
20121         echo "Time for file removal $delta sec for 1 RPC sent at a time"
20122
20123         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
20124 }
20125 run_test 182b "Test parallel modify metadata operations from osp"
20126
20127 test_183() { # LU-2275
20128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20129         remote_mds_nodsh && skip "remote MDS with nodsh"
20130         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
20131                 skip "Need MDS version at least 2.3.56"
20132
20133         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20134         echo aaa > $DIR/$tdir/$tfile
20135
20136 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
20137         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
20138
20139         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
20140         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
20141
20142         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20143
20144         # Flush negative dentry cache
20145         touch $DIR/$tdir/$tfile
20146
20147         # We are not checking for any leaked references here, they'll
20148         # become evident next time we do cleanup with module unload.
20149         rm -rf $DIR/$tdir
20150 }
20151 run_test 183 "No crash or request leak in case of strange dispositions ========"
20152
20153 # test suite 184 is for LU-2016, LU-2017
20154 test_184a() {
20155         check_swap_layouts_support
20156
20157         dir0=$DIR/$tdir/$testnum
20158         test_mkdir -p -c1 $dir0
20159         ref1=/etc/passwd
20160         ref2=/etc/group
20161         file1=$dir0/f1
20162         file2=$dir0/f2
20163         $LFS setstripe -c1 $file1
20164         cp $ref1 $file1
20165         $LFS setstripe -c2 $file2
20166         cp $ref2 $file2
20167         gen1=$($LFS getstripe -g $file1)
20168         gen2=$($LFS getstripe -g $file2)
20169
20170         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20171         gen=$($LFS getstripe -g $file1)
20172         [[ $gen1 != $gen ]] ||
20173                 error "Layout generation on $file1 does not change"
20174         gen=$($LFS getstripe -g $file2)
20175         [[ $gen2 != $gen ]] ||
20176                 error "Layout generation on $file2 does not change"
20177
20178         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20179         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20180
20181         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20182 }
20183 run_test 184a "Basic layout swap"
20184
20185 test_184b() {
20186         check_swap_layouts_support
20187
20188         dir0=$DIR/$tdir/$testnum
20189         mkdir -p $dir0 || error "creating dir $dir0"
20190         file1=$dir0/f1
20191         file2=$dir0/f2
20192         file3=$dir0/f3
20193         dir1=$dir0/d1
20194         dir2=$dir0/d2
20195         mkdir $dir1 $dir2
20196         $LFS setstripe -c1 $file1
20197         $LFS setstripe -c2 $file2
20198         $LFS setstripe -c1 $file3
20199         chown $RUNAS_ID $file3
20200         gen1=$($LFS getstripe -g $file1)
20201         gen2=$($LFS getstripe -g $file2)
20202
20203         $LFS swap_layouts $dir1 $dir2 &&
20204                 error "swap of directories layouts should fail"
20205         $LFS swap_layouts $dir1 $file1 &&
20206                 error "swap of directory and file layouts should fail"
20207         $RUNAS $LFS swap_layouts $file1 $file2 &&
20208                 error "swap of file we cannot write should fail"
20209         $LFS swap_layouts $file1 $file3 &&
20210                 error "swap of file with different owner should fail"
20211         /bin/true # to clear error code
20212 }
20213 run_test 184b "Forbidden layout swap (will generate errors)"
20214
20215 test_184c() {
20216         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20217         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20218         check_swap_layouts_support
20219         check_swap_layout_no_dom $DIR
20220
20221         local dir0=$DIR/$tdir/$testnum
20222         mkdir -p $dir0 || error "creating dir $dir0"
20223
20224         local ref1=$dir0/ref1
20225         local ref2=$dir0/ref2
20226         local file1=$dir0/file1
20227         local file2=$dir0/file2
20228         # create a file large enough for the concurrent test
20229         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20230         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20231         echo "ref file size: ref1($(stat -c %s $ref1))," \
20232              "ref2($(stat -c %s $ref2))"
20233
20234         cp $ref2 $file2
20235         dd if=$ref1 of=$file1 bs=16k &
20236         local DD_PID=$!
20237
20238         # Make sure dd starts to copy file, but wait at most 5 seconds
20239         local loops=0
20240         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20241
20242         $LFS swap_layouts $file1 $file2
20243         local rc=$?
20244         wait $DD_PID
20245         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20246         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20247
20248         # how many bytes copied before swapping layout
20249         local copied=$(stat -c %s $file2)
20250         local remaining=$(stat -c %s $ref1)
20251         remaining=$((remaining - copied))
20252         echo "Copied $copied bytes before swapping layout..."
20253
20254         cmp -n $copied $file1 $ref2 | grep differ &&
20255                 error "Content mismatch [0, $copied) of ref2 and file1"
20256         cmp -n $copied $file2 $ref1 ||
20257                 error "Content mismatch [0, $copied) of ref1 and file2"
20258         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20259                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20260
20261         # clean up
20262         rm -f $ref1 $ref2 $file1 $file2
20263 }
20264 run_test 184c "Concurrent write and layout swap"
20265
20266 test_184d() {
20267         check_swap_layouts_support
20268         check_swap_layout_no_dom $DIR
20269         [ -z "$(which getfattr 2>/dev/null)" ] &&
20270                 skip_env "no getfattr command"
20271
20272         local file1=$DIR/$tdir/$tfile-1
20273         local file2=$DIR/$tdir/$tfile-2
20274         local file3=$DIR/$tdir/$tfile-3
20275         local lovea1
20276         local lovea2
20277
20278         mkdir -p $DIR/$tdir
20279         touch $file1 || error "create $file1 failed"
20280         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20281                 error "create $file2 failed"
20282         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20283                 error "create $file3 failed"
20284         lovea1=$(get_layout_param $file1)
20285
20286         $LFS swap_layouts $file2 $file3 ||
20287                 error "swap $file2 $file3 layouts failed"
20288         $LFS swap_layouts $file1 $file2 ||
20289                 error "swap $file1 $file2 layouts failed"
20290
20291         lovea2=$(get_layout_param $file2)
20292         echo "$lovea1"
20293         echo "$lovea2"
20294         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20295
20296         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20297         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20298 }
20299 run_test 184d "allow stripeless layouts swap"
20300
20301 test_184e() {
20302         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20303                 skip "Need MDS version at least 2.6.94"
20304         check_swap_layouts_support
20305         check_swap_layout_no_dom $DIR
20306         [ -z "$(which getfattr 2>/dev/null)" ] &&
20307                 skip_env "no getfattr command"
20308
20309         local file1=$DIR/$tdir/$tfile-1
20310         local file2=$DIR/$tdir/$tfile-2
20311         local file3=$DIR/$tdir/$tfile-3
20312         local lovea
20313
20314         mkdir -p $DIR/$tdir
20315         touch $file1 || error "create $file1 failed"
20316         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20317                 error "create $file2 failed"
20318         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20319                 error "create $file3 failed"
20320
20321         $LFS swap_layouts $file1 $file2 ||
20322                 error "swap $file1 $file2 layouts failed"
20323
20324         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20325         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20326
20327         echo 123 > $file1 || error "Should be able to write into $file1"
20328
20329         $LFS swap_layouts $file1 $file3 ||
20330                 error "swap $file1 $file3 layouts failed"
20331
20332         echo 123 > $file1 || error "Should be able to write into $file1"
20333
20334         rm -rf $file1 $file2 $file3
20335 }
20336 run_test 184e "Recreate layout after stripeless layout swaps"
20337
20338 test_184f() {
20339         # Create a file with name longer than sizeof(struct stat) ==
20340         # 144 to see if we can get chars from the file name to appear
20341         # in the returned striping. Note that 'f' == 0x66.
20342         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20343
20344         mkdir -p $DIR/$tdir
20345         mcreate $DIR/$tdir/$file
20346         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20347                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20348         fi
20349 }
20350 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20351
20352 test_185() { # LU-2441
20353         # LU-3553 - no volatile file support in old servers
20354         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20355                 skip "Need MDS version at least 2.3.60"
20356
20357         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20358         touch $DIR/$tdir/spoo
20359         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20360         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20361                 error "cannot create/write a volatile file"
20362         [ "$FILESET" == "" ] &&
20363         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20364                 error "FID is still valid after close"
20365
20366         multiop_bg_pause $DIR/$tdir Vw4096_c
20367         local multi_pid=$!
20368
20369         local OLD_IFS=$IFS
20370         IFS=":"
20371         local fidv=($fid)
20372         IFS=$OLD_IFS
20373         # assume that the next FID for this client is sequential, since stdout
20374         # is unfortunately eaten by multiop_bg_pause
20375         local n=$((${fidv[1]} + 1))
20376         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20377         if [ "$FILESET" == "" ]; then
20378                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20379                         error "FID is missing before close"
20380         fi
20381         kill -USR1 $multi_pid
20382         # 1 second delay, so if mtime change we will see it
20383         sleep 1
20384         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20385         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20386 }
20387 run_test 185 "Volatile file support"
20388
20389 function create_check_volatile() {
20390         local idx=$1
20391         local tgt
20392
20393         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20394         local PID=$!
20395         sleep 1
20396         local FID=$(cat /tmp/${tfile}.fid)
20397         [ "$FID" == "" ] && error "can't get FID for volatile"
20398         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20399         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20400         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20401         kill -USR1 $PID
20402         wait
20403         sleep 1
20404         cancel_lru_locks mdc # flush opencache
20405         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20406         return 0
20407 }
20408
20409 test_185a(){
20410         # LU-12516 - volatile creation via .lustre
20411         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20412                 skip "Need MDS version at least 2.3.55"
20413
20414         create_check_volatile 0
20415         [ $MDSCOUNT -lt 2 ] && return 0
20416
20417         # DNE case
20418         create_check_volatile 1
20419
20420         return 0
20421 }
20422 run_test 185a "Volatile file creation in .lustre/fid/"
20423
20424 test_187a() {
20425         remote_mds_nodsh && skip "remote MDS with nodsh"
20426         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20427                 skip "Need MDS version at least 2.3.0"
20428
20429         local dir0=$DIR/$tdir/$testnum
20430         mkdir -p $dir0 || error "creating dir $dir0"
20431
20432         local file=$dir0/file1
20433         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20434         stack_trap "rm -f $file"
20435         local dv1=$($LFS data_version $file)
20436         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20437         local dv2=$($LFS data_version $file)
20438         [[ $dv1 != $dv2 ]] ||
20439                 error "data version did not change on write $dv1 == $dv2"
20440 }
20441 run_test 187a "Test data version change"
20442
20443 test_187b() {
20444         remote_mds_nodsh && skip "remote MDS with nodsh"
20445         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20446                 skip "Need MDS version at least 2.3.0"
20447
20448         local dir0=$DIR/$tdir/$testnum
20449         mkdir -p $dir0 || error "creating dir $dir0"
20450
20451         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20452         [[ ${DV[0]} != ${DV[1]} ]] ||
20453                 error "data version did not change on write"\
20454                       " ${DV[0]} == ${DV[1]}"
20455
20456         # clean up
20457         rm -f $file1
20458 }
20459 run_test 187b "Test data version change on volatile file"
20460
20461 test_200() {
20462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20463         remote_mgs_nodsh && skip "remote MGS with nodsh"
20464         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20465
20466         local POOL=${POOL:-cea1}
20467         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20468         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20469         # Pool OST targets
20470         local first_ost=0
20471         local last_ost=$(($OSTCOUNT - 1))
20472         local ost_step=2
20473         local ost_list=$(seq $first_ost $ost_step $last_ost)
20474         local ost_range="$first_ost $last_ost $ost_step"
20475         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20476         local file_dir=$POOL_ROOT/file_tst
20477         local subdir=$test_path/subdir
20478         local rc=0
20479
20480         while : ; do
20481                 # former test_200a test_200b
20482                 pool_add $POOL                          || { rc=$? ; break; }
20483                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20484                 # former test_200c test_200d
20485                 mkdir -p $test_path
20486                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20487                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20488                 mkdir -p $subdir
20489                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20490                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20491                                                         || { rc=$? ; break; }
20492                 # former test_200e test_200f
20493                 local files=$((OSTCOUNT*3))
20494                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20495                                                         || { rc=$? ; break; }
20496                 pool_create_files $POOL $file_dir $files "$ost_list" \
20497                                                         || { rc=$? ; break; }
20498                 # former test_200g test_200h
20499                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20500                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20501
20502                 # former test_201a test_201b test_201c
20503                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20504
20505                 local f=$test_path/$tfile
20506                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20507                 pool_remove $POOL $f                    || { rc=$? ; break; }
20508                 break
20509         done
20510
20511         destroy_test_pools
20512
20513         return $rc
20514 }
20515 run_test 200 "OST pools"
20516
20517 # usage: default_attr <count | size | offset>
20518 default_attr() {
20519         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20520 }
20521
20522 # usage: check_default_stripe_attr
20523 check_default_stripe_attr() {
20524         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20525         case $1 in
20526         --stripe-count|-c)
20527                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20528         --stripe-size|-S)
20529                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20530         --stripe-index|-i)
20531                 EXPECTED=-1;;
20532         *)
20533                 error "unknown getstripe attr '$1'"
20534         esac
20535
20536         [ $ACTUAL == $EXPECTED ] ||
20537                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20538 }
20539
20540 test_204a() {
20541         test_mkdir $DIR/$tdir
20542         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20543
20544         check_default_stripe_attr --stripe-count
20545         check_default_stripe_attr --stripe-size
20546         check_default_stripe_attr --stripe-index
20547 }
20548 run_test 204a "Print default stripe attributes"
20549
20550 test_204b() {
20551         test_mkdir $DIR/$tdir
20552         $LFS setstripe --stripe-count 1 $DIR/$tdir
20553
20554         check_default_stripe_attr --stripe-size
20555         check_default_stripe_attr --stripe-index
20556 }
20557 run_test 204b "Print default stripe size and offset"
20558
20559 test_204c() {
20560         test_mkdir $DIR/$tdir
20561         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20562
20563         check_default_stripe_attr --stripe-count
20564         check_default_stripe_attr --stripe-index
20565 }
20566 run_test 204c "Print default stripe count and offset"
20567
20568 test_204d() {
20569         test_mkdir $DIR/$tdir
20570         $LFS setstripe --stripe-index 0 $DIR/$tdir
20571
20572         check_default_stripe_attr --stripe-count
20573         check_default_stripe_attr --stripe-size
20574 }
20575 run_test 204d "Print default stripe count and size"
20576
20577 test_204e() {
20578         test_mkdir $DIR/$tdir
20579         $LFS setstripe -d $DIR/$tdir
20580
20581         # LU-16904 check if root is set as PFL layout
20582         local numcomp=$($LFS getstripe --component-count $MOUNT)
20583
20584         if [[ $numcomp -gt 0 ]]; then
20585                 check_default_stripe_attr --stripe-count
20586         else
20587                 check_default_stripe_attr --stripe-count --raw
20588         fi
20589         check_default_stripe_attr --stripe-size --raw
20590         check_default_stripe_attr --stripe-index --raw
20591 }
20592 run_test 204e "Print raw stripe attributes"
20593
20594 test_204f() {
20595         test_mkdir $DIR/$tdir
20596         $LFS setstripe --stripe-count 1 $DIR/$tdir
20597
20598         check_default_stripe_attr --stripe-size --raw
20599         check_default_stripe_attr --stripe-index --raw
20600 }
20601 run_test 204f "Print raw stripe size and offset"
20602
20603 test_204g() {
20604         test_mkdir $DIR/$tdir
20605         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20606
20607         check_default_stripe_attr --stripe-count --raw
20608         check_default_stripe_attr --stripe-index --raw
20609 }
20610 run_test 204g "Print raw stripe count and offset"
20611
20612 test_204h() {
20613         test_mkdir $DIR/$tdir
20614         $LFS setstripe --stripe-index 0 $DIR/$tdir
20615
20616         check_default_stripe_attr --stripe-count --raw
20617         check_default_stripe_attr --stripe-size --raw
20618 }
20619 run_test 204h "Print raw stripe count and size"
20620
20621 # Figure out which job scheduler is being used, if any,
20622 # or use a fake one
20623 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20624         JOBENV=SLURM_JOB_ID
20625 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20626         JOBENV=LSB_JOBID
20627 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20628         JOBENV=PBS_JOBID
20629 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20630         JOBENV=LOADL_STEP_ID
20631 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20632         JOBENV=JOB_ID
20633 else
20634         $LCTL list_param jobid_name > /dev/null 2>&1
20635         if [ $? -eq 0 ]; then
20636                 JOBENV=nodelocal
20637         else
20638                 JOBENV=FAKE_JOBID
20639         fi
20640 fi
20641 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20642
20643 verify_jobstats() {
20644         local cmd=($1)
20645         shift
20646         local facets="$@"
20647
20648 # we don't really need to clear the stats for this test to work, since each
20649 # command has a unique jobid, but it makes debugging easier if needed.
20650 #       for facet in $facets; do
20651 #               local dev=$(convert_facet2label $facet)
20652 #               # clear old jobstats
20653 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20654 #       done
20655
20656         # use a new JobID for each test, or we might see an old one
20657         [ "$JOBENV" = "FAKE_JOBID" ] &&
20658                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20659
20660         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20661
20662         [ "$JOBENV" = "nodelocal" ] && {
20663                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20664                 $LCTL set_param jobid_name=$FAKE_JOBID
20665                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20666         }
20667
20668         log "Test: ${cmd[*]}"
20669         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20670
20671         if [ $JOBENV = "FAKE_JOBID" ]; then
20672                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20673         else
20674                 ${cmd[*]}
20675         fi
20676
20677         # all files are created on OST0000
20678         for facet in $facets; do
20679                 local stats="*.$(convert_facet2label $facet).job_stats"
20680
20681                 # strip out libtool wrappers for in-tree executables
20682                 if (( $(do_facet $facet lctl get_param $stats |
20683                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20684                         do_facet $facet lctl get_param $stats
20685                         error "No jobstats for $JOBVAL found on $facet::$stats"
20686                 fi
20687         done
20688 }
20689
20690 jobstats_set() {
20691         local new_jobenv=$1
20692
20693         set_persistent_param_and_check client "jobid_var" \
20694                 "$FSNAME.sys.jobid_var" $new_jobenv
20695 }
20696
20697 test_205a() { # Job stats
20698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20699         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20700                 skip "Need MDS version with at least 2.7.1"
20701         remote_mgs_nodsh && skip "remote MGS with nodsh"
20702         remote_mds_nodsh && skip "remote MDS with nodsh"
20703         remote_ost_nodsh && skip "remote OST with nodsh"
20704         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20705                 skip "Server doesn't support jobstats"
20706         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20707
20708         local old_jobenv=$($LCTL get_param -n jobid_var)
20709         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20710         stack_trap "jobstats_set $old_jobenv" EXIT
20711
20712         changelog_register
20713
20714         local old_jobid_name=$($LCTL get_param jobid_name)
20715         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20716
20717         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20718                                 mdt.*.job_cleanup_interval | head -n 1)
20719         local new_interval=5
20720         do_facet $SINGLEMDS \
20721                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20722         stack_trap "do_facet $SINGLEMDS \
20723                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20724         local start=$SECONDS
20725
20726         local cmd
20727         # mkdir
20728         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20729         verify_jobstats "$cmd" "$SINGLEMDS"
20730         # rmdir
20731         cmd="rmdir $DIR/$tdir"
20732         verify_jobstats "$cmd" "$SINGLEMDS"
20733         # mkdir on secondary MDT
20734         if [ $MDSCOUNT -gt 1 ]; then
20735                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20736                 verify_jobstats "$cmd" "mds2"
20737         fi
20738         # mknod
20739         cmd="mknod $DIR/$tfile c 1 3"
20740         verify_jobstats "$cmd" "$SINGLEMDS"
20741         # unlink
20742         cmd="rm -f $DIR/$tfile"
20743         verify_jobstats "$cmd" "$SINGLEMDS"
20744         # create all files on OST0000 so verify_jobstats can find OST stats
20745         # open & close
20746         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20747         verify_jobstats "$cmd" "$SINGLEMDS"
20748         # setattr
20749         cmd="touch $DIR/$tfile"
20750         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20751         # write
20752         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20753         verify_jobstats "$cmd" "ost1"
20754         # read
20755         cancel_lru_locks osc
20756         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20757         verify_jobstats "$cmd" "ost1"
20758         # truncate
20759         cmd="$TRUNCATE $DIR/$tfile 0"
20760         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20761         # rename
20762         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20763         verify_jobstats "$cmd" "$SINGLEMDS"
20764         # jobstats expiry - sleep until old stats should be expired
20765         local left=$((new_interval + 5 - (SECONDS - start)))
20766         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20767                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20768                         "0" $left
20769         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20770         verify_jobstats "$cmd" "$SINGLEMDS"
20771         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20772             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20773
20774         # Ensure that jobid are present in changelog (if supported by MDS)
20775         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20776                 changelog_dump | tail -10
20777                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20778                 [ $jobids -eq 9 ] ||
20779                         error "Wrong changelog jobid count $jobids != 9"
20780
20781                 # LU-5862
20782                 JOBENV="disable"
20783                 jobstats_set $JOBENV
20784                 touch $DIR/$tfile
20785                 changelog_dump | grep $tfile
20786                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20787                 [ $jobids -eq 0 ] ||
20788                         error "Unexpected jobids when jobid_var=$JOBENV"
20789         fi
20790
20791         # test '%j' access to environment variable - if supported
20792         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20793                 JOBENV="JOBCOMPLEX"
20794                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20795
20796                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20797         fi
20798
20799         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20800                 JOBENV="JOBCOMPLEX"
20801                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20802
20803                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20804         fi
20805
20806         # test '%j' access to per-session jobid - if supported
20807         if lctl list_param jobid_this_session > /dev/null 2>&1
20808         then
20809                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20810                 lctl set_param jobid_this_session=$USER
20811
20812                 JOBENV="JOBCOMPLEX"
20813                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20814
20815                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20816         fi
20817 }
20818 run_test 205a "Verify job stats"
20819
20820 # LU-13117, LU-13597, LU-16599
20821 test_205b() {
20822         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20823                 skip "Need MDS version at least 2.13.54.91"
20824
20825         local job_stats="mdt.*.job_stats"
20826         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20827
20828         do_facet mds1 $LCTL set_param $job_stats=clear
20829
20830         # Setting jobid_var to USER might not be supported
20831         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20832         $LCTL set_param jobid_var=USER || true
20833         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20834         $LCTL set_param jobid_name="%j.%e.%u"
20835
20836         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20837         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20838                 { do_facet mds1 $LCTL get_param $job_stats;
20839                   error "Unexpected jobid found"; }
20840         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20841                 { do_facet mds1 $LCTL get_param $job_stats;
20842                   error "wrong job_stats format found"; }
20843
20844         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20845                 echo "MDS does not yet escape jobid" && return 0
20846
20847         mkdir_on_mdt0 $DIR/$tdir
20848         $LCTL set_param jobid_var=TEST205b
20849         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20850         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20851                       awk '/has\\x20sp/ {print $3}')
20852         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20853                   error "jobid not escaped"; }
20854
20855         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20856                 # need to run such a command on mds1:
20857                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20858                 #
20859                 # there might be multiple MDTs on single mds server, so need to
20860                 # specifiy MDT0000. Or the command will fail due to other MDTs
20861                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20862                         error "cannot clear escaped jobid in job_stats";
20863         else
20864                 echo "MDS does not support clearing escaped jobid"
20865         fi
20866 }
20867 run_test 205b "Verify job stats jobid and output format"
20868
20869 # LU-13733
20870 test_205c() {
20871         $LCTL set_param llite.*.stats=0
20872         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20873         $LCTL get_param llite.*.stats
20874         $LCTL get_param llite.*.stats | grep \
20875                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20876                         error "wrong client stats format found"
20877 }
20878 run_test 205c "Verify client stats format"
20879
20880 test_205d() {
20881         local file=$DIR/$tdir/$tfile
20882
20883         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20884                 skip "need lustre >= 2.15.53 for lljobstat"
20885         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20886                 skip "need lustre >= 2.15.53 for lljobstat"
20887         verify_yaml_available || skip_env "YAML verification not installed"
20888
20889         test_mkdir -i 0 $DIR/$tdir
20890         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20891         stack_trap "rm -rf $DIR/$tdir"
20892
20893         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20894                 error "failed to write data to $file"
20895         mv $file $file.2
20896
20897         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20898         echo -n 'verify rename_stats...'
20899         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20900                 verify_yaml || error "rename_stats is not valid YAML"
20901         echo " OK"
20902
20903         echo -n 'verify mdt job_stats...'
20904         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20905                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20906         echo " OK"
20907
20908         echo -n 'verify ost job_stats...'
20909         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20910                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20911         echo " OK"
20912 }
20913 run_test 205d "verify the format of some stats files"
20914
20915 test_205e() {
20916         local ops_comma
20917         local file=$DIR/$tdir/$tfile
20918         local -a cli_params
20919
20920         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20921                 skip "need lustre >= 2.15.53 for lljobstat"
20922         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20923                 skip "need lustre >= 2.15.53 for lljobstat"
20924         verify_yaml_available || skip_env "YAML verification not installed"
20925
20926         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20927         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20928         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20929
20930         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20931         stack_trap "rm -rf $DIR/$tdir"
20932
20933         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20934                 error "failed to create $file on ost1"
20935         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20936                 error "failed to write data to $file"
20937
20938         do_facet mds1 "$LCTL get_param *.*.job_stats"
20939         do_facet ost1 "$LCTL get_param *.*.job_stats"
20940
20941         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20942         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20943                 error "The output of lljobstat is not an valid YAML"
20944
20945         # verify that job dd.0 does exist and has some ops on ost1
20946         # typically this line is like:
20947         # - 205e.dd.0:            {ops: 20, ...}
20948         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20949                     awk '$2=="205e.dd.0:" {print $4}')
20950
20951         (( ${ops_comma%,} >= 10 )) ||
20952                 error "cannot find job 205e.dd.0 with ops >= 10"
20953 }
20954 run_test 205e "verify the output of lljobstat"
20955
20956 test_205f() {
20957         verify_yaml_available || skip_env "YAML verification not installed"
20958
20959         # check both qos_ost_weights and qos_mdt_weights
20960         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20961         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20962                 error "qos_ost_weights is not valid YAML"
20963 }
20964 run_test 205f "verify qos_ost_weights YAML format "
20965
20966 __test_205_jobstats_dump() {
20967         local -a pids
20968         local nbr_instance=$1
20969
20970         while true; do
20971                 if (( ${#pids[@]} >= nbr_instance )); then
20972                         wait ${pids[@]}
20973                         pids=()
20974                 fi
20975
20976                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20977                 pids+=( $! )
20978         done
20979 }
20980
20981 __test_205_cleanup() {
20982         kill $@
20983         # Clear all job entries
20984         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20985 }
20986
20987 test_205g() {
20988         local -a mds1_params
20989         local -a cli_params
20990         local pids
20991         local interval=5
20992
20993         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20994         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20995         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20996
20997         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20998         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20999         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
21000
21001         # start jobs loop
21002         export TEST205G_ID=205g
21003         stack_trap "unset TEST205G_ID" EXIT
21004         while true; do
21005                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
21006         done & pids="$! "
21007
21008         __test_205_jobstats_dump 4 & pids+="$! "
21009         stack_trap "__test_205_cleanup $pids" EXIT INT
21010
21011         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
21012 }
21013 run_test 205g "stress test for job_stats procfile"
21014
21015 test_205h() {
21016         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
21017                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
21018         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
21019
21020         local dir=$DIR/$tdir
21021         local f=$dir/$tfile
21022         local f2=$dir/$tfile-2
21023         local f3=$dir/$tfile-3
21024         local subdir=$DIR/dir
21025         local val
21026
21027         local mdts=$(comma_list $(mdts_nodes))
21028         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
21029         local client_saved=$($LCTL get_param -n jobid_var)
21030
21031         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
21032         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
21033
21034         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
21035                 error "failed to set job_xattr parameter to user.job"
21036         $LCTL set_param jobid_var=procname.uid ||
21037                 error "failed to set jobid_var parameter"
21038
21039         test_mkdir $dir
21040
21041         touch $f
21042         val=$(getfattr -n user.job $f | grep user.job)
21043         [[ $val = user.job=\"touch.0\" ]] ||
21044                 error "expected user.job=\"touch.0\", got '$val'"
21045
21046         mkdir $subdir
21047         val=$(getfattr -n user.job $subdir | grep user.job)
21048         [[ $val = user.job=\"mkdir.0\" ]] ||
21049                 error "expected user.job=\"mkdir.0\", got '$val'"
21050
21051         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
21052                 error "failed to set job_xattr parameter to NONE"
21053
21054         touch $f2
21055         val=$(getfattr -d $f2)
21056         [[ -z $val ]] ||
21057                 error "expected no user xattr, got '$val'"
21058
21059         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
21060                 error "failed to set job_xattr parameter to trusted.job"
21061
21062         touch $f3
21063         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
21064         [[ $val = trusted.job=\"touch.0\" ]] ||
21065                 error "expected trusted.job=\"touch.0\", got '$val'"
21066 }
21067 run_test 205h "check jobid xattr is stored correctly"
21068
21069 test_205i() {
21070         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
21071                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
21072
21073         local mdts=$(comma_list $(mdts_nodes))
21074         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
21075
21076         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
21077
21078         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
21079                 error "failed to set mdt.*.job_xattr to user.1234567"
21080
21081         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
21082                 error "failed to reject too long job_xattr name"
21083
21084         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
21085                 error "failed to reject job_xattr name in bad format"
21086
21087         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
21088                 error "failed to reject job_xattr name with invalid character"
21089
21090         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
21091                         xargs $LCTL set_param" &&
21092                 error "failed to reject job_xattr name with non-ascii character"
21093
21094         return 0
21095 }
21096 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
21097
21098 # LU-1480, LU-1773 and LU-1657
21099 test_206() {
21100         mkdir -p $DIR/$tdir
21101         $LFS setstripe -c -1 $DIR/$tdir
21102 #define OBD_FAIL_LOV_INIT 0x1403
21103         $LCTL set_param fail_loc=0xa0001403
21104         $LCTL set_param fail_val=1
21105         touch $DIR/$tdir/$tfile || true
21106 }
21107 run_test 206 "fail lov_init_raid0() doesn't lbug"
21108
21109 test_207a() {
21110         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21111         local fsz=`stat -c %s $DIR/$tfile`
21112         cancel_lru_locks mdc
21113
21114         # do not return layout in getattr intent
21115 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
21116         $LCTL set_param fail_loc=0x170
21117         local sz=`stat -c %s $DIR/$tfile`
21118
21119         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
21120
21121         rm -rf $DIR/$tfile
21122 }
21123 run_test 207a "can refresh layout at glimpse"
21124
21125 test_207b() {
21126         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21127         local cksum=`md5sum $DIR/$tfile`
21128         local fsz=`stat -c %s $DIR/$tfile`
21129         cancel_lru_locks mdc
21130         cancel_lru_locks osc
21131
21132         # do not return layout in getattr intent
21133 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
21134         $LCTL set_param fail_loc=0x171
21135
21136         # it will refresh layout after the file is opened but before read issues
21137         echo checksum is "$cksum"
21138         echo "$cksum" |md5sum -c --quiet || error "file differs"
21139
21140         rm -rf $DIR/$tfile
21141 }
21142 run_test 207b "can refresh layout at open"
21143
21144 test_208() {
21145         # FIXME: in this test suite, only RD lease is used. This is okay
21146         # for now as only exclusive open is supported. After generic lease
21147         # is done, this test suite should be revised. - Jinshan
21148
21149         remote_mds_nodsh && skip "remote MDS with nodsh"
21150         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21151                 skip "Need MDS version at least 2.4.52"
21152
21153         echo "==== test 1: verify get lease work"
21154         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21155
21156         echo "==== test 2: verify lease can be broken by upcoming open"
21157         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21158         local PID=$!
21159         sleep 2
21160
21161         $MULTIOP $DIR/$tfile oO_RDWR:c
21162         kill -USR1 $PID && wait $PID || error "break lease error"
21163
21164         echo "==== test 3: verify lease can't be granted if an open already exists"
21165         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21166         local PID=$!
21167         sleep 2
21168
21169         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21170         kill -USR1 $PID && wait $PID || error "open file error"
21171
21172         echo "==== test 4: lease can sustain over recovery"
21173         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21174         PID=$!
21175         sleep 2
21176
21177         fail mds1
21178
21179         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21180
21181         echo "==== test 5: lease broken can't be regained by replay"
21182         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21183         PID=$!
21184         sleep 2
21185
21186         # open file to break lease and then recovery
21187         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21188         fail mds1
21189
21190         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21191
21192         rm -f $DIR/$tfile
21193 }
21194 run_test 208 "Exclusive open"
21195
21196 test_209() {
21197         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21198                 skip_env "must have disp_stripe"
21199
21200         touch $DIR/$tfile
21201         sync; sleep 5; sync;
21202
21203         echo 3 > /proc/sys/vm/drop_caches
21204         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21205                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21206         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21207
21208         # open/close 500 times
21209         for i in $(seq 500); do
21210                 cat $DIR/$tfile
21211         done
21212
21213         echo 3 > /proc/sys/vm/drop_caches
21214         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21215                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21216         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21217
21218         echo "before: $req_before, after: $req_after"
21219         [ $((req_after - req_before)) -ge 300 ] &&
21220                 error "open/close requests are not freed"
21221         return 0
21222 }
21223 run_test 209 "read-only open/close requests should be freed promptly"
21224
21225 test_210() {
21226         local pid
21227
21228         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21229         pid=$!
21230         sleep 1
21231
21232         $LFS getstripe $DIR/$tfile
21233         kill -USR1 $pid
21234         wait $pid || error "multiop failed"
21235
21236         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21237         pid=$!
21238         sleep 1
21239
21240         $LFS getstripe $DIR/$tfile
21241         kill -USR1 $pid
21242         wait $pid || error "multiop failed"
21243 }
21244 run_test 210 "lfs getstripe does not break leases"
21245
21246 function test_211() {
21247         local PID
21248         local id
21249         local rc
21250
21251         stack_trap "rm -f $DIR/$tfile" EXIT
21252         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21253                 error "can't create file"
21254         $LFS mirror extend -N $DIR/$tfile ||
21255                 error "can't create a replica"
21256         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21257         $LFS getstripe $DIR/$tfile
21258         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21259         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21260
21261         $MULTIOP $DIR/$tfile OeW_E+eUc &
21262         PID=$!
21263         sleep 0.3
21264
21265         id=$($LFS getstripe $DIR/$tfile |
21266                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21267         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21268                 error "removed last in-sync replica?"
21269
21270         kill -USR1 $PID
21271         wait $PID
21272         (( $? == 0 )) || error "failed split broke the lease"
21273 }
21274 run_test 211 "failed mirror split doesn't break write lease"
21275
21276 test_212() {
21277         size=`date +%s`
21278         size=$((size % 8192 + 1))
21279         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21280         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21281         rm -f $DIR/f212 $DIR/f212.xyz
21282 }
21283 run_test 212 "Sendfile test ============================================"
21284
21285 test_213() {
21286         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21287         cancel_lru_locks osc
21288         lctl set_param fail_loc=0x8000040f
21289         # generate a read lock
21290         cat $DIR/$tfile > /dev/null
21291         # write to the file, it will try to cancel the above read lock.
21292         cat /etc/hosts >> $DIR/$tfile
21293 }
21294 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21295
21296 test_214() { # for bug 20133
21297         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21298         for (( i=0; i < 340; i++ )) ; do
21299                 touch $DIR/$tdir/d214c/a$i
21300         done
21301
21302         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21303         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21304         ls $DIR/d214c || error "ls $DIR/d214c failed"
21305         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21306         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21307 }
21308 run_test 214 "hash-indexed directory test - bug 20133"
21309
21310 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21311 create_lnet_proc_files() {
21312         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21313 }
21314
21315 # counterpart of create_lnet_proc_files
21316 remove_lnet_proc_files() {
21317         rm -f $TMP/lnet_$1.sys
21318 }
21319
21320 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21321 # 3rd arg as regexp for body
21322 check_lnet_proc_stats() {
21323         local l=$(cat "$TMP/lnet_$1" |wc -l)
21324         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21325
21326         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21327 }
21328
21329 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21330 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21331 # optional and can be regexp for 2nd line (lnet.routes case)
21332 check_lnet_proc_entry() {
21333         local blp=2          # blp stands for 'position of 1st line of body'
21334         [ -z "$5" ] || blp=3 # lnet.routes case
21335
21336         local l=$(cat "$TMP/lnet_$1" |wc -l)
21337         # subtracting one from $blp because the body can be empty
21338         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21339
21340         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21341                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21342
21343         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21344                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21345
21346         # bail out if any unexpected line happened
21347         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21348         [ "$?" != 0 ] || error "$2 misformatted"
21349 }
21350
21351 test_215() { # for bugs 18102, 21079, 21517
21352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21353
21354         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21355         local P='[1-9][0-9]*'           # positive numeric
21356         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21357         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21358         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21359         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21360         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21361         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21362
21363         local L1 # regexp for 1st line
21364         local L2 # regexp for 2nd line (optional)
21365         local BR # regexp for the rest (body)
21366
21367         # lnet.stats should look as 11 space-separated non-negative numerics
21368         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21369         create_lnet_proc_files "stats"
21370         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21371         remove_lnet_proc_files "stats"
21372
21373         # lnet.routes should look like this:
21374         # Routing disabled/enabled
21375         # net hops priority state router
21376         # where net is a string like tcp0, hops > 0, priority >= 0,
21377         # state is up/down,
21378         # router is a string like 192.168.1.1@tcp2
21379         L1="^Routing (disabled|enabled)$"
21380         L2="^net +hops +priority +state +router$"
21381         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21382         create_lnet_proc_files "routes"
21383         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21384         remove_lnet_proc_files "routes"
21385
21386         # lnet.routers should look like this:
21387         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21388         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21389         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21390         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21391         L1="^ref +rtr_ref +alive +router$"
21392         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21393         create_lnet_proc_files "routers"
21394         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21395         remove_lnet_proc_files "routers"
21396
21397         # lnet.peers should look like this:
21398         # nid refs state last max rtr min tx min queue
21399         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21400         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21401         # numeric (0 or >0 or <0), queue >= 0.
21402         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21403         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21404         create_lnet_proc_files "peers"
21405         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21406         remove_lnet_proc_files "peers"
21407
21408         # lnet.buffers  should look like this:
21409         # pages count credits min
21410         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21411         L1="^pages +count +credits +min$"
21412         BR="^ +$N +$N +$I +$I$"
21413         create_lnet_proc_files "buffers"
21414         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21415         remove_lnet_proc_files "buffers"
21416
21417         # lnet.nis should look like this:
21418         # nid status alive refs peer rtr max tx min
21419         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21420         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21421         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21422         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21423         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21424         create_lnet_proc_files "nis"
21425         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21426         remove_lnet_proc_files "nis"
21427
21428         # can we successfully write to lnet.stats?
21429         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21430 }
21431 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21432
21433 test_216() { # bug 20317
21434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21435         remote_ost_nodsh && skip "remote OST with nodsh"
21436
21437         local node
21438         local facets=$(get_facets OST)
21439         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21440
21441         save_lustre_params client "osc.*.contention_seconds" > $p
21442         save_lustre_params $facets \
21443                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21444         save_lustre_params $facets \
21445                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21446         save_lustre_params $facets \
21447                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21448         clear_stats osc.*.osc_stats
21449
21450         # agressive lockless i/o settings
21451         do_nodes $(comma_list $(osts_nodes)) \
21452                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21453                         ldlm.namespaces.filter-*.contended_locks=0 \
21454                         ldlm.namespaces.filter-*.contention_seconds=60"
21455         lctl set_param -n osc.*.contention_seconds=60
21456
21457         $DIRECTIO write $DIR/$tfile 0 10 4096
21458         $CHECKSTAT -s 40960 $DIR/$tfile
21459
21460         # disable lockless i/o
21461         do_nodes $(comma_list $(osts_nodes)) \
21462                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21463                         ldlm.namespaces.filter-*.contended_locks=32 \
21464                         ldlm.namespaces.filter-*.contention_seconds=0"
21465         lctl set_param -n osc.*.contention_seconds=0
21466         clear_stats osc.*.osc_stats
21467
21468         dd if=/dev/zero of=$DIR/$tfile count=0
21469         $CHECKSTAT -s 0 $DIR/$tfile
21470
21471         restore_lustre_params <$p
21472         rm -f $p
21473         rm $DIR/$tfile
21474 }
21475 run_test 216 "check lockless direct write updates file size and kms correctly"
21476
21477 test_217() { # bug 22430
21478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21479
21480         local node
21481
21482         for node in $(nodes_list); do
21483                 local nid=$(host_nids_address $node $NETTYPE)
21484                 local node_ip=$(do_node $node getent ahostsv4 $node |
21485                                 awk '{ print $1; exit; }')
21486
21487                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21488                 # if hostname matches any NID, use hostname for better testing
21489                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21490                         echo "lctl ping node $node@$NETTYPE"
21491                         lctl ping $node@$NETTYPE ||
21492                                 error "ping $node@$NETTYPE failed rc=$?"
21493                 else # otherwise, at least test 'lctl ping' is working
21494                         echo "lctl ping nid $(h2nettype $nid)"
21495                         lctl ping $(h2nettype $nid) ||
21496                                 error "ping $(h2nettype $nid) failed rc=$?"
21497                         echo "skipping $node (no hyphen detected)"
21498                 fi
21499         done
21500
21501         return 0
21502 }
21503 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21504
21505 test_218() {
21506         # do directio so as not to populate the page cache
21507         log "creating a 10 Mb file"
21508         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21509                 error "multiop failed while creating a file"
21510         log "starting reads"
21511         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21512         log "truncating the file"
21513         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21514                 error "multiop failed while truncating the file"
21515         log "killing dd"
21516         kill %+ || true # reads might have finished
21517         echo "wait until dd is finished"
21518         wait
21519         log "removing the temporary file"
21520         rm -rf $DIR/$tfile || error "tmp file removal failed"
21521 }
21522 run_test 218 "parallel read and truncate should not deadlock"
21523
21524 test_219() {
21525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21526
21527         # write one partial page
21528         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21529         # set no grant so vvp_io_commit_write will do sync write
21530         $LCTL set_param fail_loc=0x411
21531         # write a full page at the end of file
21532         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21533
21534         $LCTL set_param fail_loc=0
21535         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21536         $LCTL set_param fail_loc=0x411
21537         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21538
21539         # LU-4201
21540         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21541         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21542 }
21543 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21544
21545 test_220() { #LU-325
21546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21547         remote_ost_nodsh && skip "remote OST with nodsh"
21548         remote_mds_nodsh && skip "remote MDS with nodsh"
21549         remote_mgs_nodsh && skip "remote MGS with nodsh"
21550
21551         local OSTIDX=0
21552
21553         # create on MDT0000 so the last_id and next_id are correct
21554         mkdir_on_mdt0 $DIR/$tdir
21555         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21556         OST=${OST%_UUID}
21557
21558         # on the mdt's osc
21559         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21560         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21561                         osp.$mdtosc_proc1.prealloc_last_id)
21562         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21563                         osp.$mdtosc_proc1.prealloc_next_id)
21564
21565         $LFS df -i
21566
21567         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21568         #define OBD_FAIL_OST_ENOINO              0x229
21569         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21570         create_pool $FSNAME.$TESTNAME || return 1
21571         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21572
21573         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21574
21575         MDSOBJS=$((last_id - next_id))
21576         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21577
21578         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21579         echo "OST still has $count kbytes free"
21580
21581         echo "create $MDSOBJS files @next_id..."
21582         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21583
21584         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21585                         osp.$mdtosc_proc1.prealloc_last_id)
21586         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21587                         osp.$mdtosc_proc1.prealloc_next_id)
21588
21589         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21590         $LFS df -i
21591
21592         echo "cleanup..."
21593
21594         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21595         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21596
21597         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21598                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21599         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21600                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21601         echo "unlink $MDSOBJS files @$next_id..."
21602         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21603 }
21604 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21605
21606 test_221() {
21607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21608
21609         dd if=`which date` of=$MOUNT/date oflag=sync
21610         chmod +x $MOUNT/date
21611
21612         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21613         $LCTL set_param fail_loc=0x80001401
21614
21615         $MOUNT/date > /dev/null
21616         rm -f $MOUNT/date
21617 }
21618 run_test 221 "make sure fault and truncate race to not cause OOM"
21619
21620 test_222a () {
21621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21622
21623         rm -rf $DIR/$tdir
21624         test_mkdir $DIR/$tdir
21625         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21626         createmany -o $DIR/$tdir/$tfile 10
21627         cancel_lru_locks mdc
21628         cancel_lru_locks osc
21629         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21630         $LCTL set_param fail_loc=0x31a
21631         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21632         $LCTL set_param fail_loc=0
21633         rm -r $DIR/$tdir
21634 }
21635 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21636
21637 test_222b () {
21638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21639
21640         rm -rf $DIR/$tdir
21641         test_mkdir $DIR/$tdir
21642         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21643         createmany -o $DIR/$tdir/$tfile 10
21644         cancel_lru_locks mdc
21645         cancel_lru_locks osc
21646         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21647         $LCTL set_param fail_loc=0x31a
21648         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21649         $LCTL set_param fail_loc=0
21650 }
21651 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21652
21653 test_223 () {
21654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21655
21656         rm -rf $DIR/$tdir
21657         test_mkdir $DIR/$tdir
21658         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21659         createmany -o $DIR/$tdir/$tfile 10
21660         cancel_lru_locks mdc
21661         cancel_lru_locks osc
21662         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21663         $LCTL set_param fail_loc=0x31b
21664         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21665         $LCTL set_param fail_loc=0
21666         rm -r $DIR/$tdir
21667 }
21668 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21669
21670 test_224a() { # LU-1039, MRP-303
21671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21672         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21673         $LCTL set_param fail_loc=0x508
21674         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21675         $LCTL set_param fail_loc=0
21676         df $DIR
21677 }
21678 run_test 224a "Don't panic on bulk IO failure"
21679
21680 test_224bd_sub() { # LU-1039, MRP-303
21681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21682         local timeout=$1
21683
21684         shift
21685         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21686
21687         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21688
21689         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21690         cancel_lru_locks osc
21691         set_checksums 0
21692         stack_trap "set_checksums $ORIG_CSUM" EXIT
21693         local at_max_saved=0
21694
21695         # adaptive timeouts may prevent seeing the issue
21696         if at_is_enabled; then
21697                 at_max_saved=$(at_max_get mds)
21698                 at_max_set 0 mds client
21699                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21700         fi
21701
21702         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21703         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21704         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21705
21706         do_facet ost1 $LCTL set_param fail_loc=0
21707         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21708         df $DIR
21709 }
21710
21711 test_224b() {
21712         test_224bd_sub 3 error "dd failed"
21713 }
21714 run_test 224b "Don't panic on bulk IO failure"
21715
21716 test_224c() { # LU-6441
21717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21718         remote_mds_nodsh && skip "remote MDS with nodsh"
21719
21720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21721         save_writethrough $p
21722         set_cache writethrough on
21723
21724         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21725         local at_max=$($LCTL get_param -n at_max)
21726         local timeout=$($LCTL get_param -n timeout)
21727         local test_at="at_max"
21728         local param_at="$FSNAME.sys.at_max"
21729         local test_timeout="timeout"
21730         local param_timeout="$FSNAME.sys.timeout"
21731
21732         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21733
21734         set_persistent_param_and_check client "$test_at" "$param_at" 0
21735         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21736
21737         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21738         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21739         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21740         stack_trap "rm -f $DIR/$tfile"
21741         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21742         sync
21743         do_facet ost1 "$LCTL set_param fail_loc=0"
21744
21745         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21746         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21747                 $timeout
21748
21749         $LCTL set_param -n $pages_per_rpc
21750         restore_lustre_params < $p
21751         rm -f $p
21752 }
21753 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21754
21755 test_224d() { # LU-11169
21756         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21757 }
21758 run_test 224d "Don't corrupt data on bulk IO timeout"
21759
21760 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21761 test_225a () {
21762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21763         if [ -z ${MDSSURVEY} ]; then
21764                 skip_env "mds-survey not found"
21765         fi
21766         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21767                 skip "Need MDS version at least 2.2.51"
21768
21769         local mds=$(facet_host $SINGLEMDS)
21770         local target=$(do_nodes $mds 'lctl dl' |
21771                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21772
21773         local cmd1="file_count=1000 thrhi=4"
21774         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21775         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21776         local cmd="$cmd1 $cmd2 $cmd3"
21777
21778         rm -f ${TMP}/mds_survey*
21779         echo + $cmd
21780         eval $cmd || error "mds-survey with zero-stripe failed"
21781         cat ${TMP}/mds_survey*
21782         rm -f ${TMP}/mds_survey*
21783 }
21784 run_test 225a "Metadata survey sanity with zero-stripe"
21785
21786 test_225b () {
21787         if [ -z ${MDSSURVEY} ]; then
21788                 skip_env "mds-survey not found"
21789         fi
21790         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21791                 skip "Need MDS version at least 2.2.51"
21792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21793         remote_mds_nodsh && skip "remote MDS with nodsh"
21794         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21795                 skip_env "Need to mount OST to test"
21796         fi
21797
21798         local mds=$(facet_host $SINGLEMDS)
21799         local target=$(do_nodes $mds 'lctl dl' |
21800                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21801
21802         local cmd1="file_count=1000 thrhi=4"
21803         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21804         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21805         local cmd="$cmd1 $cmd2 $cmd3"
21806
21807         rm -f ${TMP}/mds_survey*
21808         echo + $cmd
21809         eval $cmd || error "mds-survey with stripe_count failed"
21810         cat ${TMP}/mds_survey*
21811         rm -f ${TMP}/mds_survey*
21812 }
21813 run_test 225b "Metadata survey sanity with stripe_count = 1"
21814
21815 mcreate_path2fid () {
21816         local mode=$1
21817         local major=$2
21818         local minor=$3
21819         local name=$4
21820         local desc=$5
21821         local path=$DIR/$tdir/$name
21822         local fid
21823         local rc
21824         local fid_path
21825
21826         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21827                 error "cannot create $desc"
21828
21829         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21830         rc=$?
21831         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21832
21833         fid_path=$($LFS fid2path $MOUNT $fid)
21834         rc=$?
21835         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21836
21837         [ "$path" == "$fid_path" ] ||
21838                 error "fid2path returned $fid_path, expected $path"
21839
21840         echo "pass with $path and $fid"
21841 }
21842
21843 test_226a () {
21844         rm -rf $DIR/$tdir
21845         mkdir -p $DIR/$tdir
21846
21847         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21848         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21849         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21850         mcreate_path2fid 0040666 0 0 dir "directory"
21851         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21852         mcreate_path2fid 0100666 0 0 file "regular file"
21853         mcreate_path2fid 0120666 0 0 link "symbolic link"
21854         mcreate_path2fid 0140666 0 0 sock "socket"
21855 }
21856 run_test 226a "call path2fid and fid2path on files of all type"
21857
21858 test_226b () {
21859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21860
21861         local MDTIDX=1
21862
21863         rm -rf $DIR/$tdir
21864         mkdir -p $DIR/$tdir
21865         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21866                 error "create remote directory failed"
21867         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21868         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21869                                 "character special file (null)"
21870         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21871                                 "character special file (no device)"
21872         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21873         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21874                                 "block special file (loop)"
21875         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21876         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21877         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21878 }
21879 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21880
21881 test_226c () {
21882         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21883         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21884                 skip "Need MDS version at least 2.13.55"
21885
21886         local submnt=/mnt/submnt
21887         local srcfile=/etc/passwd
21888         local dstfile=$submnt/passwd
21889         local path
21890         local fid
21891
21892         rm -rf $DIR/$tdir
21893         rm -rf $submnt
21894         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21895                 error "create remote directory failed"
21896         mkdir -p $submnt || error "create $submnt failed"
21897         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21898                 error "mount $submnt failed"
21899         stack_trap "umount $submnt" EXIT
21900
21901         cp $srcfile $dstfile
21902         fid=$($LFS path2fid $dstfile)
21903         path=$($LFS fid2path $submnt "$fid")
21904         [ "$path" = "$dstfile" ] ||
21905                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21906 }
21907 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21908
21909 test_226d () {
21910         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21911                 skip "Need client at least version 2.15.57"
21912
21913         # Define First test dataset
21914         local testdirs_01=$DIR/$tdir
21915         local testdata_01=$testdirs_01/${tdir}_01
21916         local testresult_01=${tdir}_01
21917         # Define Second test dataset
21918         local testdirs_02=$DIR/$tdir/$tdir
21919         local testdata_02=$testdirs_02/${tdir}_02
21920         local testresult_02=${tdir}_02
21921         # Define third test dataset (top level)
21922         local testdata_03=$DIR/${tdir}_03
21923         local testresult_03=${tdir}_03
21924
21925         # Create first test dataset
21926         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21927         touch $testdata_01 || error "cannot create file $testdata_01"
21928
21929         # Create second test dataset
21930         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21931         touch $testdata_02 || error "cannot create file $testdata_02"
21932
21933         # Create third test dataset
21934         touch $testdata_03 || error "cannot create file $testdata_03"
21935
21936         local fid01=$($LFS getstripe -F "$testdata_01") ||
21937                 error "getstripe failed on $testdata_01"
21938         local fid02=$($LFS getstripe -F "$testdata_02") ||
21939                 error "getstripe failed on $testdata_01"
21940         local fid03=$($LFS getstripe -F "$testdata_03") ||
21941                 error "getstripe failed on $testdata_03"
21942
21943         # Verify only -n option
21944         local out1=$($LFS fid2path -n $DIR $fid01) ||
21945                 error "fid2path failed on $fid01"
21946         local out2=$($LFS fid2path -n $DIR $fid02) ||
21947                 error "fid2path failed on $fid02"
21948         local out3=$($LFS fid2path -n $DIR $fid03) ||
21949                 error "fid2path failed on $fid03"
21950
21951         [[ "$out1" == "$testresult_01" ]] ||
21952                 error "fid2path failed: Expected $testresult_01 got $out1"
21953         [[ "$out2" == "$testresult_02" ]] ||
21954                 error "fid2path failed: Expected $testresult_02 got $out2"
21955         [[ "$out3" == "$testresult_03" ]] ||
21956                 error "fid2path failed: Expected $testresult_03 got $out3"
21957
21958         # Verify with option -fn together
21959         out1=$($LFS fid2path -fn $DIR $fid01) ||
21960                 error "fid2path -fn failed on $fid01"
21961         out2=$($LFS fid2path -fn $DIR $fid02) ||
21962                 error "fid2path -fn failed on $fid02"
21963         out3=$($LFS fid2path -fn $DIR $fid03) ||
21964                 error "fid2path -fn failed on $fid03"
21965
21966         local tmpout=$(echo $out1 | cut -d" " -f2)
21967         [[ "$tmpout" == "$testresult_01" ]] ||
21968                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21969
21970         tmpout=$(echo $out2 | cut -d" " -f2)
21971         [[ "$tmpout" == "$testresult_02" ]] ||
21972                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21973
21974         tmpout=$(echo $out3 | cut -d" " -f2)
21975         [[ "$tmpout" == "$testresult_03" ]] ||
21976                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21977 }
21978 run_test 226d "verify fid2path with -n and -fn option"
21979
21980 test_226e () {
21981         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21982                 skip "Need client at least version 2.15.56"
21983
21984         # Define filename with 'newline' and a space
21985         local testfile="Test"$'\n'"file 01"
21986         # Define link name with multiple 'newline' and a space
21987         local linkfile="Link"$'\n'"file "$'\n'"01"
21988         # Remove prior hard link
21989         rm -f $DIR/"$linkfile"
21990
21991         # Create file
21992         touch $DIR/"$testfile"
21993         # Create link
21994         ln $DIR/"$testfile" $DIR/"$linkfile"
21995
21996         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21997                 error "getstripe failed on $DIR/$testfile"
21998
21999         # Call with -0 option
22000         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
22001                 echo "FILE:" | grep -c "FILE:")
22002
22003         # With -0 option the output should be exactly 2 lines.
22004         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
22005 }
22006 run_test 226e "Verify path2fid -0 option with newline and space"
22007
22008 # LU-1299 Executing or running ldd on a truncated executable does not
22009 # cause an out-of-memory condition.
22010 test_227() {
22011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22012         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
22013
22014         dd if=$(which date) of=$MOUNT/date bs=1k count=1
22015         chmod +x $MOUNT/date
22016
22017         $MOUNT/date > /dev/null
22018         ldd $MOUNT/date > /dev/null
22019         rm -f $MOUNT/date
22020 }
22021 run_test 227 "running truncated executable does not cause OOM"
22022
22023 # LU-1512 try to reuse idle OI blocks
22024 test_228a() {
22025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22026         remote_mds_nodsh && skip "remote MDS with nodsh"
22027         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22028
22029         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22030         local myDIR=$DIR/$tdir
22031
22032         mkdir -p $myDIR
22033         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22034         $LCTL set_param fail_loc=0x80001002
22035         createmany -o $myDIR/t- 10000
22036         $LCTL set_param fail_loc=0
22037         # The guard is current the largest FID holder
22038         touch $myDIR/guard
22039         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22040                     tr -d '[')
22041         local IDX=$(($SEQ % 64))
22042
22043         do_facet $SINGLEMDS sync
22044         # Make sure journal flushed.
22045         sleep 6
22046         local blk1=$(do_facet $SINGLEMDS \
22047                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22048                      grep Blockcount | awk '{print $4}')
22049
22050         # Remove old files, some OI blocks will become idle.
22051         unlinkmany $myDIR/t- 10000
22052         # Create new files, idle OI blocks should be reused.
22053         createmany -o $myDIR/t- 2000
22054         do_facet $SINGLEMDS sync
22055         # Make sure journal flushed.
22056         sleep 6
22057         local blk2=$(do_facet $SINGLEMDS \
22058                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22059                      grep Blockcount | awk '{print $4}')
22060
22061         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22062 }
22063 run_test 228a "try to reuse idle OI blocks"
22064
22065 test_228b() {
22066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22067         remote_mds_nodsh && skip "remote MDS with nodsh"
22068         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22069
22070         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22071         local myDIR=$DIR/$tdir
22072
22073         mkdir -p $myDIR
22074         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22075         $LCTL set_param fail_loc=0x80001002
22076         createmany -o $myDIR/t- 10000
22077         $LCTL set_param fail_loc=0
22078         # The guard is current the largest FID holder
22079         touch $myDIR/guard
22080         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22081                     tr -d '[')
22082         local IDX=$(($SEQ % 64))
22083
22084         do_facet $SINGLEMDS sync
22085         # Make sure journal flushed.
22086         sleep 6
22087         local blk1=$(do_facet $SINGLEMDS \
22088                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22089                      grep Blockcount | awk '{print $4}')
22090
22091         # Remove old files, some OI blocks will become idle.
22092         unlinkmany $myDIR/t- 10000
22093
22094         # stop the MDT
22095         stop $SINGLEMDS || error "Fail to stop MDT."
22096         # remount the MDT
22097         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22098                 error "Fail to start MDT."
22099
22100         client_up || error "Fail to df."
22101         # Create new files, idle OI blocks should be reused.
22102         createmany -o $myDIR/t- 2000
22103         do_facet $SINGLEMDS sync
22104         # Make sure journal flushed.
22105         sleep 6
22106         local blk2=$(do_facet $SINGLEMDS \
22107                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22108                      grep Blockcount | awk '{print $4}')
22109
22110         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22111 }
22112 run_test 228b "idle OI blocks can be reused after MDT restart"
22113
22114 #LU-1881
22115 test_228c() {
22116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22117         remote_mds_nodsh && skip "remote MDS with nodsh"
22118         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22119
22120         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22121         local myDIR=$DIR/$tdir
22122
22123         mkdir -p $myDIR
22124         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22125         $LCTL set_param fail_loc=0x80001002
22126         # 20000 files can guarantee there are index nodes in the OI file
22127         createmany -o $myDIR/t- 20000
22128         $LCTL set_param fail_loc=0
22129         # The guard is current the largest FID holder
22130         touch $myDIR/guard
22131         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22132                     tr -d '[')
22133         local IDX=$(($SEQ % 64))
22134
22135         do_facet $SINGLEMDS sync
22136         # Make sure journal flushed.
22137         sleep 6
22138         local blk1=$(do_facet $SINGLEMDS \
22139                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22140                      grep Blockcount | awk '{print $4}')
22141
22142         # Remove old files, some OI blocks will become idle.
22143         unlinkmany $myDIR/t- 20000
22144         rm -f $myDIR/guard
22145         # The OI file should become empty now
22146
22147         # Create new files, idle OI blocks should be reused.
22148         createmany -o $myDIR/t- 2000
22149         do_facet $SINGLEMDS sync
22150         # Make sure journal flushed.
22151         sleep 6
22152         local blk2=$(do_facet $SINGLEMDS \
22153                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22154                      grep Blockcount | awk '{print $4}')
22155
22156         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22157 }
22158 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22159
22160 test_229() { # LU-2482, LU-3448
22161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22162         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22163         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22164                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22165
22166         rm -f $DIR/$tfile
22167
22168         # Create a file with a released layout and stripe count 2.
22169         $MULTIOP $DIR/$tfile H2c ||
22170                 error "failed to create file with released layout"
22171
22172         $LFS getstripe -v $DIR/$tfile
22173
22174         local pattern=$($LFS getstripe -L $DIR/$tfile)
22175         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22176
22177         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22178                 error "getstripe"
22179         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22180         stat $DIR/$tfile || error "failed to stat released file"
22181
22182         chown $RUNAS_ID $DIR/$tfile ||
22183                 error "chown $RUNAS_ID $DIR/$tfile failed"
22184
22185         chgrp $RUNAS_ID $DIR/$tfile ||
22186                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22187
22188         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22189         rm $DIR/$tfile || error "failed to remove released file"
22190 }
22191 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22192
22193 test_230a() {
22194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22196         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22197                 skip "Need MDS version at least 2.11.52"
22198
22199         local MDTIDX=1
22200
22201         test_mkdir $DIR/$tdir
22202         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22203         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22204         [ $mdt_idx -ne 0 ] &&
22205                 error "create local directory on wrong MDT $mdt_idx"
22206
22207         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22208                         error "create remote directory failed"
22209         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22210         [ $mdt_idx -ne $MDTIDX ] &&
22211                 error "create remote directory on wrong MDT $mdt_idx"
22212
22213         createmany -o $DIR/$tdir/test_230/t- 10 ||
22214                 error "create files on remote directory failed"
22215         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22216         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22217         rm -r $DIR/$tdir || error "unlink remote directory failed"
22218 }
22219 run_test 230a "Create remote directory and files under the remote directory"
22220
22221 test_230b() {
22222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22224         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22225                 skip "Need MDS version at least 2.11.52"
22226
22227         local MDTIDX=1
22228         local mdt_index
22229         local i
22230         local file
22231         local pid
22232         local stripe_count
22233         local migrate_dir=$DIR/$tdir/migrate_dir
22234         local other_dir=$DIR/$tdir/other_dir
22235
22236         test_mkdir $DIR/$tdir
22237         test_mkdir -i0 -c1 $migrate_dir
22238         test_mkdir -i0 -c1 $other_dir
22239         for ((i=0; i<10; i++)); do
22240                 mkdir -p $migrate_dir/dir_${i}
22241                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22242                         error "create files under remote dir failed $i"
22243         done
22244
22245         cp /etc/passwd $migrate_dir/$tfile
22246         cp /etc/passwd $other_dir/$tfile
22247         chattr +SAD $migrate_dir
22248         chattr +SAD $migrate_dir/$tfile
22249
22250         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22251         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22252         local old_dir_mode=$(stat -c%f $migrate_dir)
22253         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22254
22255         mkdir -p $migrate_dir/dir_default_stripe2
22256         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22257         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22258
22259         mkdir -p $other_dir
22260         ln $migrate_dir/$tfile $other_dir/luna
22261         ln $migrate_dir/$tfile $migrate_dir/sofia
22262         ln $other_dir/$tfile $migrate_dir/david
22263         ln -s $migrate_dir/$tfile $other_dir/zachary
22264         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22265         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22266
22267         local len
22268         local lnktgt
22269
22270         # inline symlink
22271         for len in 58 59 60; do
22272                 lnktgt=$(str_repeat 'l' $len)
22273                 touch $migrate_dir/$lnktgt
22274                 ln -s $lnktgt $migrate_dir/${len}char_ln
22275         done
22276
22277         # PATH_MAX
22278         for len in 4094 4095; do
22279                 lnktgt=$(str_repeat 'l' $len)
22280                 ln -s $lnktgt $migrate_dir/${len}char_ln
22281         done
22282
22283         # NAME_MAX
22284         for len in 254 255; do
22285                 touch $migrate_dir/$(str_repeat 'l' $len)
22286         done
22287
22288         $LFS migrate -m $MDTIDX $migrate_dir ||
22289                 error "fails on migrating remote dir to MDT1"
22290
22291         echo "migratate to MDT1, then checking.."
22292         for ((i = 0; i < 10; i++)); do
22293                 for file in $(find $migrate_dir/dir_${i}); do
22294                         mdt_index=$($LFS getstripe -m $file)
22295                         # broken symlink getstripe will fail
22296                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22297                                 error "$file is not on MDT${MDTIDX}"
22298                 done
22299         done
22300
22301         # the multiple link file should still in MDT0
22302         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22303         [ $mdt_index == 0 ] ||
22304                 error "$file is not on MDT${MDTIDX}"
22305
22306         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22307         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22308                 error " expect $old_dir_flag get $new_dir_flag"
22309
22310         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22311         [ "$old_file_flag" = "$new_file_flag" ] ||
22312                 error " expect $old_file_flag get $new_file_flag"
22313
22314         local new_dir_mode=$(stat -c%f $migrate_dir)
22315         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22316                 error "expect mode $old_dir_mode get $new_dir_mode"
22317
22318         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22319         [ "$old_file_mode" = "$new_file_mode" ] ||
22320                 error "expect mode $old_file_mode get $new_file_mode"
22321
22322         diff /etc/passwd $migrate_dir/$tfile ||
22323                 error "$tfile different after migration"
22324
22325         diff /etc/passwd $other_dir/luna ||
22326                 error "luna different after migration"
22327
22328         diff /etc/passwd $migrate_dir/sofia ||
22329                 error "sofia different after migration"
22330
22331         diff /etc/passwd $migrate_dir/david ||
22332                 error "david different after migration"
22333
22334         diff /etc/passwd $other_dir/zachary ||
22335                 error "zachary different after migration"
22336
22337         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22338                 error "${tfile}_ln different after migration"
22339
22340         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22341                 error "${tfile}_ln_other different after migration"
22342
22343         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22344         [ $stripe_count = 2 ] ||
22345                 error "dir strpe_count $d != 2 after migration."
22346
22347         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22348         [ $stripe_count = 2 ] ||
22349                 error "file strpe_count $d != 2 after migration."
22350
22351         #migrate back to MDT0
22352         MDTIDX=0
22353
22354         $LFS migrate -m $MDTIDX $migrate_dir ||
22355                 error "fails on migrating remote dir to MDT0"
22356
22357         echo "migrate back to MDT0, checking.."
22358         for file in $(find $migrate_dir); do
22359                 mdt_index=$($LFS getstripe -m $file)
22360                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22361                         error "$file is not on MDT${MDTIDX}"
22362         done
22363
22364         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22365         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22366                 error " expect $old_dir_flag get $new_dir_flag"
22367
22368         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22369         [ "$old_file_flag" = "$new_file_flag" ] ||
22370                 error " expect $old_file_flag get $new_file_flag"
22371
22372         local new_dir_mode=$(stat -c%f $migrate_dir)
22373         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22374                 error "expect mode $old_dir_mode get $new_dir_mode"
22375
22376         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22377         [ "$old_file_mode" = "$new_file_mode" ] ||
22378                 error "expect mode $old_file_mode get $new_file_mode"
22379
22380         diff /etc/passwd ${migrate_dir}/$tfile ||
22381                 error "$tfile different after migration"
22382
22383         diff /etc/passwd ${other_dir}/luna ||
22384                 error "luna different after migration"
22385
22386         diff /etc/passwd ${migrate_dir}/sofia ||
22387                 error "sofia different after migration"
22388
22389         diff /etc/passwd ${other_dir}/zachary ||
22390                 error "zachary different after migration"
22391
22392         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22393                 error "${tfile}_ln different after migration"
22394
22395         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22396                 error "${tfile}_ln_other different after migration"
22397
22398         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22399         [ $stripe_count = 2 ] ||
22400                 error "dir strpe_count $d != 2 after migration."
22401
22402         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22403         [ $stripe_count = 2 ] ||
22404                 error "file strpe_count $d != 2 after migration."
22405
22406         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22407 }
22408 run_test 230b "migrate directory"
22409
22410 test_230c() {
22411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22413         remote_mds_nodsh && skip "remote MDS with nodsh"
22414         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22415                 skip "Need MDS version at least 2.11.52"
22416
22417         local MDTIDX=1
22418         local total=3
22419         local mdt_index
22420         local file
22421         local migrate_dir=$DIR/$tdir/migrate_dir
22422
22423         #If migrating directory fails in the middle, all entries of
22424         #the directory is still accessiable.
22425         test_mkdir $DIR/$tdir
22426         test_mkdir -i0 -c1 $migrate_dir
22427         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22428         stat $migrate_dir
22429         createmany -o $migrate_dir/f $total ||
22430                 error "create files under ${migrate_dir} failed"
22431
22432         # fail after migrating top dir, and this will fail only once, so the
22433         # first sub file migration will fail (currently f3), others succeed.
22434         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22435         do_facet mds1 lctl set_param fail_loc=0x1801
22436         local t=$(ls $migrate_dir | wc -l)
22437         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22438                 error "migrate should fail"
22439         local u=$(ls $migrate_dir | wc -l)
22440         [ "$u" == "$t" ] || error "$u != $t during migration"
22441
22442         # add new dir/file should succeed
22443         mkdir $migrate_dir/dir ||
22444                 error "mkdir failed under migrating directory"
22445         touch $migrate_dir/file ||
22446                 error "create file failed under migrating directory"
22447
22448         # add file with existing name should fail
22449         for file in $migrate_dir/f*; do
22450                 stat $file > /dev/null || error "stat $file failed"
22451                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22452                         error "open(O_CREAT|O_EXCL) $file should fail"
22453                 $MULTIOP $file m && error "create $file should fail"
22454                 touch $DIR/$tdir/remote_dir/$tfile ||
22455                         error "touch $tfile failed"
22456                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22457                         error "link $file should fail"
22458                 mdt_index=$($LFS getstripe -m $file)
22459                 if [ $mdt_index == 0 ]; then
22460                         # file failed to migrate is not allowed to rename to
22461                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22462                                 error "rename to $file should fail"
22463                 else
22464                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22465                                 error "rename to $file failed"
22466                 fi
22467                 echo hello >> $file || error "write $file failed"
22468         done
22469
22470         # resume migration with different options should fail
22471         $LFS migrate -m 0 $migrate_dir &&
22472                 error "migrate -m 0 $migrate_dir should fail"
22473
22474         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22475                 error "migrate -c 2 $migrate_dir should fail"
22476
22477         # resume migration should succeed
22478         $LFS migrate -m $MDTIDX $migrate_dir ||
22479                 error "migrate $migrate_dir failed"
22480
22481         echo "Finish migration, then checking.."
22482         for file in $(find $migrate_dir); do
22483                 mdt_index=$($LFS getstripe -m $file)
22484                 [ $mdt_index == $MDTIDX ] ||
22485                         error "$file is not on MDT${MDTIDX}"
22486         done
22487
22488         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22489 }
22490 run_test 230c "check directory accessiblity if migration failed"
22491
22492 test_230d() {
22493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22495         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22496                 skip "Need MDS version at least 2.11.52"
22497         # LU-11235
22498         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22499
22500         local migrate_dir=$DIR/$tdir/migrate_dir
22501         local old_index
22502         local new_index
22503         local old_count
22504         local new_count
22505         local new_hash
22506         local mdt_index
22507         local i
22508         local j
22509
22510         old_index=$((RANDOM % MDSCOUNT))
22511         old_count=$((MDSCOUNT - old_index))
22512         new_index=$((RANDOM % MDSCOUNT))
22513         new_count=$((MDSCOUNT - new_index))
22514         new_hash=1 # for all_char
22515
22516         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22517         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22518
22519         test_mkdir $DIR/$tdir
22520         test_mkdir -i $old_index -c $old_count $migrate_dir
22521
22522         for ((i=0; i<100; i++)); do
22523                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22524                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22525                         error "create files under remote dir failed $i"
22526         done
22527
22528         echo -n "Migrate from MDT$old_index "
22529         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22530         echo -n "to MDT$new_index"
22531         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22532         echo
22533
22534         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22535         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22536                 error "migrate remote dir error"
22537
22538         echo "Finish migration, then checking.."
22539         for file in $(find $migrate_dir -maxdepth 1); do
22540                 mdt_index=$($LFS getstripe -m $file)
22541                 if [ $mdt_index -lt $new_index ] ||
22542                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22543                         error "$file is on MDT$mdt_index"
22544                 fi
22545         done
22546
22547         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22548 }
22549 run_test 230d "check migrate big directory"
22550
22551 test_230e() {
22552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22553         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22554         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22555                 skip "Need MDS version at least 2.11.52"
22556
22557         local i
22558         local j
22559         local a_fid
22560         local b_fid
22561
22562         mkdir_on_mdt0 $DIR/$tdir
22563         mkdir $DIR/$tdir/migrate_dir
22564         mkdir $DIR/$tdir/other_dir
22565         touch $DIR/$tdir/migrate_dir/a
22566         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22567         ls $DIR/$tdir/other_dir
22568
22569         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22570                 error "migrate dir fails"
22571
22572         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22573         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22574
22575         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22576         [ $mdt_index == 0 ] || error "a is not on MDT0"
22577
22578         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22579                 error "migrate dir fails"
22580
22581         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22582         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22583
22584         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22585         [ $mdt_index == 1 ] || error "a is not on MDT1"
22586
22587         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22588         [ $mdt_index == 1 ] || error "b is not on MDT1"
22589
22590         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22591         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22592
22593         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22594
22595         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22596 }
22597 run_test 230e "migrate mulitple local link files"
22598
22599 test_230f() {
22600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22602         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22603                 skip "Need MDS version at least 2.11.52"
22604
22605         local a_fid
22606         local ln_fid
22607
22608         mkdir -p $DIR/$tdir
22609         mkdir $DIR/$tdir/migrate_dir
22610         $LFS mkdir -i1 $DIR/$tdir/other_dir
22611         touch $DIR/$tdir/migrate_dir/a
22612         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22613         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22614         ls $DIR/$tdir/other_dir
22615
22616         # a should be migrated to MDT1, since no other links on MDT0
22617         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22618                 error "#1 migrate dir fails"
22619         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22620         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22621         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22622         [ $mdt_index == 1 ] || error "a is not on MDT1"
22623
22624         # a should stay on MDT1, because it is a mulitple link file
22625         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22626                 error "#2 migrate dir fails"
22627         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22628         [ $mdt_index == 1 ] || error "a is not on MDT1"
22629
22630         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22631                 error "#3 migrate dir fails"
22632
22633         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22634         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22635         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22636
22637         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22638         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22639
22640         # a should be migrated to MDT0, since no other links on MDT1
22641         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22642                 error "#4 migrate dir fails"
22643         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22644         [ $mdt_index == 0 ] || error "a is not on MDT0"
22645
22646         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22647 }
22648 run_test 230f "migrate mulitple remote link files"
22649
22650 test_230g() {
22651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22652         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22653         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22654                 skip "Need MDS version at least 2.11.52"
22655
22656         mkdir -p $DIR/$tdir/migrate_dir
22657
22658         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22659                 error "migrating dir to non-exist MDT succeeds"
22660         true
22661 }
22662 run_test 230g "migrate dir to non-exist MDT"
22663
22664 test_230h() {
22665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22666         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22667         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22668                 skip "Need MDS version at least 2.11.52"
22669
22670         local mdt_index
22671
22672         mkdir -p $DIR/$tdir/migrate_dir
22673
22674         $LFS migrate -m1 $DIR &&
22675                 error "migrating mountpoint1 should fail"
22676
22677         $LFS migrate -m1 $DIR/$tdir/.. &&
22678                 error "migrating mountpoint2 should fail"
22679
22680         # same as mv
22681         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22682                 error "migrating $tdir/migrate_dir/.. should fail"
22683
22684         true
22685 }
22686 run_test 230h "migrate .. and root"
22687
22688 test_230i() {
22689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22690         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22691         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22692                 skip "Need MDS version at least 2.11.52"
22693
22694         mkdir -p $DIR/$tdir/migrate_dir
22695
22696         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22697                 error "migration fails with a tailing slash"
22698
22699         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22700                 error "migration fails with two tailing slashes"
22701 }
22702 run_test 230i "lfs migrate -m tolerates trailing slashes"
22703
22704 test_230j() {
22705         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22706         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22707                 skip "Need MDS version at least 2.11.52"
22708
22709         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22710         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22711                 error "create $tfile failed"
22712         cat /etc/passwd > $DIR/$tdir/$tfile
22713
22714         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22715
22716         cmp /etc/passwd $DIR/$tdir/$tfile ||
22717                 error "DoM file mismatch after migration"
22718 }
22719 run_test 230j "DoM file data not changed after dir migration"
22720
22721 test_230k() {
22722         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22723         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22724                 skip "Need MDS version at least 2.11.56"
22725
22726         local total=20
22727         local files_on_starting_mdt=0
22728
22729         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22730         $LFS getdirstripe $DIR/$tdir
22731         for i in $(seq $total); do
22732                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22733                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22734                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22735         done
22736
22737         echo "$files_on_starting_mdt files on MDT0"
22738
22739         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22740         $LFS getdirstripe $DIR/$tdir
22741
22742         files_on_starting_mdt=0
22743         for i in $(seq $total); do
22744                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22745                         error "file $tfile.$i mismatch after migration"
22746                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22747                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22748         done
22749
22750         echo "$files_on_starting_mdt files on MDT1 after migration"
22751         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22752
22753         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22754         $LFS getdirstripe $DIR/$tdir
22755
22756         files_on_starting_mdt=0
22757         for i in $(seq $total); do
22758                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22759                         error "file $tfile.$i mismatch after 2nd migration"
22760                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22761                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22762         done
22763
22764         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22765         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22766
22767         true
22768 }
22769 run_test 230k "file data not changed after dir migration"
22770
22771 test_230l() {
22772         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22773         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22774                 skip "Need MDS version at least 2.11.56"
22775
22776         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22777         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22778                 error "create files under remote dir failed $i"
22779         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22780 }
22781 run_test 230l "readdir between MDTs won't crash"
22782
22783 test_230m() {
22784         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22785         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22786                 skip "Need MDS version at least 2.11.56"
22787
22788         local MDTIDX=1
22789         local mig_dir=$DIR/$tdir/migrate_dir
22790         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22791         local shortstr="b"
22792         local val
22793
22794         echo "Creating files and dirs with xattrs"
22795         test_mkdir $DIR/$tdir
22796         test_mkdir -i0 -c1 $mig_dir
22797         mkdir $mig_dir/dir
22798         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22799                 error "cannot set xattr attr1 on dir"
22800         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22801                 error "cannot set xattr attr2 on dir"
22802         touch $mig_dir/dir/f0
22803         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22804                 error "cannot set xattr attr1 on file"
22805         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22806                 error "cannot set xattr attr2 on file"
22807         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22808         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22809         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22810         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22811         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22812         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22813         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22814         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22815         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22816
22817         echo "Migrating to MDT1"
22818         $LFS migrate -m $MDTIDX $mig_dir ||
22819                 error "fails on migrating dir to MDT1"
22820
22821         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22822         echo "Checking xattrs"
22823         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22824         [ "$val" = $longstr ] ||
22825                 error "expecting xattr1 $longstr on dir, found $val"
22826         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22827         [ "$val" = $shortstr ] ||
22828                 error "expecting xattr2 $shortstr on dir, found $val"
22829         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22830         [ "$val" = $longstr ] ||
22831                 error "expecting xattr1 $longstr on file, found $val"
22832         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22833         [ "$val" = $shortstr ] ||
22834                 error "expecting xattr2 $shortstr on file, found $val"
22835 }
22836 run_test 230m "xattrs not changed after dir migration"
22837
22838 test_230n() {
22839         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22840         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22841                 skip "Need MDS version at least 2.13.53"
22842
22843         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22844         cat /etc/hosts > $DIR/$tdir/$tfile
22845         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22846         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22847
22848         cmp /etc/hosts $DIR/$tdir/$tfile ||
22849                 error "File data mismatch after migration"
22850 }
22851 run_test 230n "Dir migration with mirrored file"
22852
22853 test_230o() {
22854         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22855         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22856                 skip "Need MDS version at least 2.13.52"
22857
22858         local mdts=$(comma_list $(mdts_nodes))
22859         local timeout=100
22860         local restripe_status
22861         local delta
22862         local i
22863
22864         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22865
22866         # in case "crush" hash type is not set
22867         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22868
22869         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22870                            mdt.*MDT0000.enable_dir_restripe)
22871         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22872         stack_trap "do_nodes $mdts $LCTL set_param \
22873                     mdt.*.enable_dir_restripe=$restripe_status"
22874
22875         mkdir $DIR/$tdir
22876         createmany -m $DIR/$tdir/f 100 ||
22877                 error "create files under remote dir failed $i"
22878         createmany -d $DIR/$tdir/d 100 ||
22879                 error "create dirs under remote dir failed $i"
22880
22881         for i in $(seq 2 $MDSCOUNT); do
22882                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22883                 $LFS setdirstripe -c $i $DIR/$tdir ||
22884                         error "split -c $i $tdir failed"
22885                 wait_update $HOSTNAME \
22886                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22887                         error "dir split not finished"
22888                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22889                         awk '/migrate/ {sum += $2} END { print sum }')
22890                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22891                 # delta is around total_files/stripe_count
22892                 (( $delta < 200 / (i - 1) + 4 )) ||
22893                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22894         done
22895 }
22896 run_test 230o "dir split"
22897
22898 test_230p() {
22899         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22900         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22901                 skip "Need MDS version at least 2.13.52"
22902
22903         local mdts=$(comma_list $(mdts_nodes))
22904         local timeout=100
22905         local restripe_status
22906         local delta
22907         local c
22908
22909         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22910
22911         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22912
22913         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22914                            mdt.*MDT0000.enable_dir_restripe)
22915         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22916         stack_trap "do_nodes $mdts $LCTL set_param \
22917                     mdt.*.enable_dir_restripe=$restripe_status"
22918
22919         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22920         createmany -m $DIR/$tdir/f 100 ||
22921                 error "create files under remote dir failed"
22922         createmany -d $DIR/$tdir/d 100 ||
22923                 error "create dirs under remote dir failed"
22924
22925         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22926                 local mdt_hash="crush"
22927
22928                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22929                 $LFS setdirstripe -c $c $DIR/$tdir ||
22930                         error "split -c $c $tdir failed"
22931                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22932                         mdt_hash="$mdt_hash,fixed"
22933                 elif [ $c -eq 1 ]; then
22934                         mdt_hash="none"
22935                 fi
22936                 wait_update $HOSTNAME \
22937                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22938                         error "dir merge not finished"
22939                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22940                         awk '/migrate/ {sum += $2} END { print sum }')
22941                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22942                 # delta is around total_files/stripe_count
22943                 (( delta < 200 / c + 4 )) ||
22944                         error "$delta files migrated >= $((200 / c + 4))"
22945         done
22946 }
22947 run_test 230p "dir merge"
22948
22949 test_230q() {
22950         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22951         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22952                 skip "Need MDS version at least 2.13.52"
22953
22954         local mdts=$(comma_list $(mdts_nodes))
22955         local saved_threshold=$(do_facet mds1 \
22956                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22957         local saved_delta=$(do_facet mds1 \
22958                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22959         local threshold=100
22960         local delta=2
22961         local total=0
22962         local stripe_count=0
22963         local stripe_index
22964         local nr_files
22965         local create
22966
22967         # test with fewer files on ZFS
22968         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22969
22970         stack_trap "do_nodes $mdts $LCTL set_param \
22971                     mdt.*.dir_split_count=$saved_threshold"
22972         stack_trap "do_nodes $mdts $LCTL set_param \
22973                     mdt.*.dir_split_delta=$saved_delta"
22974         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22975         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22976         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22977         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22978         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22979         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22980
22981         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22982         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22983
22984         create=$((threshold * 3 / 2))
22985         while [ $stripe_count -lt $MDSCOUNT ]; do
22986                 createmany -m $DIR/$tdir/f $total $create ||
22987                         error "create sub files failed"
22988                 stat $DIR/$tdir > /dev/null
22989                 total=$((total + create))
22990                 stripe_count=$((stripe_count + delta))
22991                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22992
22993                 wait_update $HOSTNAME \
22994                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22995                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22996
22997                 wait_update $HOSTNAME \
22998                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22999                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
23000
23001                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
23002                 echo "$nr_files/$total files on MDT$stripe_index after split"
23003                 # allow 10% margin of imbalance with crush hash
23004                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
23005                         error "$nr_files files on MDT$stripe_index after split"
23006
23007                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
23008                 [ $nr_files -eq $total ] ||
23009                         error "total sub files $nr_files != $total"
23010         done
23011
23012         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
23013
23014         echo "fixed layout directory won't auto split"
23015         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
23016         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
23017                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
23018         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
23019                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
23020 }
23021 run_test 230q "dir auto split"
23022
23023 test_230r() {
23024         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
23025         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
23026         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
23027                 skip "Need MDS version at least 2.13.54"
23028
23029         # maximum amount of local locks:
23030         # parent striped dir - 2 locks
23031         # new stripe in parent to migrate to - 1 lock
23032         # source and target - 2 locks
23033         # Total 5 locks for regular file
23034         mkdir -p $DIR/$tdir
23035         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
23036         touch $DIR/$tdir/dir1/eee
23037
23038         # create 4 hardlink for 4 more locks
23039         # Total: 9 locks > RS_MAX_LOCKS (8)
23040         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
23041         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
23042         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
23043         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
23044         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
23045         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
23046         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
23047         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
23048
23049         cancel_lru_locks mdc
23050
23051         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
23052                 error "migrate dir fails"
23053
23054         rm -rf $DIR/$tdir || error "rm dir failed after migration"
23055 }
23056 run_test 230r "migrate with too many local locks"
23057
23058 test_230s() {
23059         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
23060                 skip "Need MDS version at least 2.14.52"
23061
23062         local mdts=$(comma_list $(mdts_nodes))
23063         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
23064                                 mdt.*MDT0000.enable_dir_restripe)
23065
23066         stack_trap "do_nodes $mdts $LCTL set_param \
23067                     mdt.*.enable_dir_restripe=$restripe_status"
23068
23069         local st
23070         for st in 0 1; do
23071                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
23072                 test_mkdir $DIR/$tdir
23073                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
23074                         error "$LFS mkdir should return EEXIST if target exists"
23075                 rmdir $DIR/$tdir
23076         done
23077 }
23078 run_test 230s "lfs mkdir should return -EEXIST if target exists"
23079
23080 test_230t()
23081 {
23082         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23083         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
23084                 skip "Need MDS version at least 2.14.50"
23085
23086         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
23087         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
23088         $LFS project -p 1 -s $DIR/$tdir ||
23089                 error "set $tdir project id failed"
23090         $LFS project -p 2 -s $DIR/$tdir/subdir ||
23091                 error "set subdir project id failed"
23092         local pbefore="$($LFS project -d $DIR/$tdir)"
23093         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
23094         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
23095
23096         local pafter="$($LFS project -d $DIR/$tdir)"
23097         local safter="$($LFS project -d $DIR/$tdir/subdir)"
23098         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
23099         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
23100
23101         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
23102                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
23103
23104         # check rename works, even if source parent projid differs (LU-17016)
23105         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
23106         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
23107
23108         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
23109         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
23110                 error "subdir failed rename for different source parent projid"
23111         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
23112
23113         [[ "$fid_before" == "$fid_after" ]] ||
23114                 error "fid before '$fid_before' != after '$fid_after'"
23115 }
23116 run_test 230t "migrate directory with project ID set"
23117
23118 test_230u()
23119 {
23120         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23121         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23122                 skip "Need MDS version at least 2.14.53"
23123
23124         local count
23125
23126         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23127         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23128         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
23129         for i in $(seq 0 $((MDSCOUNT - 1))); do
23130                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23131                 echo "$count dirs migrated to MDT$i"
23132         done
23133         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23134         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
23135 }
23136 run_test 230u "migrate directory by QOS"
23137
23138 test_230v()
23139 {
23140         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23141         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23142                 skip "Need MDS version at least 2.14.53"
23143
23144         local count
23145
23146         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23147         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23148         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23149         for i in $(seq 0 $((MDSCOUNT - 1))); do
23150                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23151                 echo "$count subdirs migrated to MDT$i"
23152                 (( i == 3 )) && (( count > 0 )) &&
23153                         error "subdir shouldn't be migrated to MDT3"
23154         done
23155         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23156         (( count == 3 )) || error "dirs migrated to $count MDTs"
23157 }
23158 run_test 230v "subdir migrated to the MDT where its parent is located"
23159
23160 test_230w() {
23161         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23162         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23163                 skip "Need MDS version at least 2.15.0"
23164
23165         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23166         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23167         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23168
23169         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23170                 error "migrate failed"
23171
23172         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23173                 error "$tdir stripe count mismatch"
23174
23175         for i in $(seq 0 9); do
23176                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23177                         error "d$i is striped"
23178         done
23179 }
23180 run_test 230w "non-recursive mode dir migration"
23181
23182 test_230x() {
23183         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23184         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23185                 skip "Need MDS version at least 2.15.0"
23186
23187         mkdir -p $DIR/$tdir || error "mkdir failed"
23188         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23189
23190         local mdt_name=$(mdtname_from_index 0)
23191         local low=$(do_facet mds2 $LCTL get_param -n \
23192                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23193         local high=$(do_facet mds2 $LCTL get_param -n \
23194                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23195         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23196         local maxage=$(do_facet mds2 $LCTL get_param -n \
23197                 osp.*$mdt_name-osp-MDT0001.maxage)
23198
23199         stack_trap "do_facet mds2 $LCTL set_param -n \
23200                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23201                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23202         stack_trap "do_facet mds2 $LCTL set_param -n \
23203                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23204
23205         do_facet mds2 $LCTL set_param -n \
23206                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23207         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23208         sleep 4
23209         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23210                 error "migrate $tdir should fail"
23211
23212         do_facet mds2 $LCTL set_param -n \
23213                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23214         do_facet mds2 $LCTL set_param -n \
23215                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23216         sleep 4
23217         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23218                 error "migrate failed"
23219         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23220                 error "$tdir stripe count mismatch"
23221 }
23222 run_test 230x "dir migration check space"
23223
23224 test_230y() {
23225         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23226         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23227                 skip "Need MDS version at least 2.15.55.45"
23228
23229         local pid
23230
23231         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23232         $LFS getdirstripe $DIR/$tdir
23233         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23234         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23235         pid=$!
23236         sleep 1
23237
23238         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23239         do_facet mds2 lctl set_param fail_loc=0x1802
23240
23241         wait $pid
23242         do_facet mds2 lctl set_param fail_loc=0
23243         $LFS getdirstripe $DIR/$tdir
23244         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23245         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23246 }
23247 run_test 230y "unlink dir with bad hash type"
23248
23249 test_230z() {
23250         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23251         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23252                 skip "Need MDS version at least 2.15.55.45"
23253
23254         local pid
23255
23256         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23257         $LFS getdirstripe $DIR/$tdir
23258         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23259         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23260         pid=$!
23261         sleep 1
23262
23263         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23264         do_facet mds2 lctl set_param fail_loc=0x1802
23265
23266         wait $pid
23267         do_facet mds2 lctl set_param fail_loc=0
23268         $LFS getdirstripe $DIR/$tdir
23269
23270         # resume migration
23271         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23272                 error "resume migration failed"
23273         $LFS getdirstripe $DIR/$tdir
23274         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23275                 error "migration is not finished"
23276 }
23277 run_test 230z "resume dir migration with bad hash type"
23278
23279 test_231a()
23280 {
23281         # For simplicity this test assumes that max_pages_per_rpc
23282         # is the same across all OSCs
23283         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23284         local bulk_size=$((max_pages * PAGE_SIZE))
23285         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23286                                        head -n 1)
23287
23288         mkdir -p $DIR/$tdir
23289         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23290                 error "failed to set stripe with -S ${brw_size}M option"
23291         stack_trap "rm -rf $DIR/$tdir"
23292
23293         # clear the OSC stats
23294         $LCTL set_param osc.*.stats=0 &>/dev/null
23295         stop_writeback
23296
23297         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23298         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23299                 oflag=direct &>/dev/null || error "dd failed"
23300
23301         sync; sleep 1; sync # just to be safe
23302         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23303         if [ x$nrpcs != "x1" ]; then
23304                 $LCTL get_param osc.*.stats
23305                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23306         fi
23307
23308         start_writeback
23309         # Drop the OSC cache, otherwise we will read from it
23310         cancel_lru_locks osc
23311
23312         # clear the OSC stats
23313         $LCTL set_param osc.*.stats=0 &>/dev/null
23314
23315         # Client reads $bulk_size.
23316         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23317                 iflag=direct &>/dev/null || error "dd failed"
23318
23319         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23320         if [ x$nrpcs != "x1" ]; then
23321                 $LCTL get_param osc.*.stats
23322                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23323         fi
23324 }
23325 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23326
23327 test_231b() {
23328         mkdir -p $DIR/$tdir
23329         stack_trap "rm -rf $DIR/$tdir"
23330         local i
23331         for i in {0..1023}; do
23332                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23333                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23334                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23335         done
23336         sync
23337 }
23338 run_test 231b "must not assert on fully utilized OST request buffer"
23339
23340 test_232a() {
23341         mkdir -p $DIR/$tdir
23342         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23343
23344         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23345         do_facet ost1 $LCTL set_param fail_loc=0x31c
23346
23347         # ignore dd failure
23348         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23349         stack_trap "rm -f $DIR/$tdir/$tfile"
23350
23351         do_facet ost1 $LCTL set_param fail_loc=0
23352         umount_client $MOUNT || error "umount failed"
23353         mount_client $MOUNT || error "mount failed"
23354         stop ost1 || error "cannot stop ost1"
23355         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23356 }
23357 run_test 232a "failed lock should not block umount"
23358
23359 test_232b() {
23360         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23361                 skip "Need MDS version at least 2.10.58"
23362
23363         mkdir -p $DIR/$tdir
23364         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23365         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23366         stack_trap "rm -f $DIR/$tdir/$tfile"
23367         sync
23368         cancel_lru_locks osc
23369
23370         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23371         do_facet ost1 $LCTL set_param fail_loc=0x31c
23372
23373         # ignore failure
23374         $LFS data_version $DIR/$tdir/$tfile || true
23375
23376         do_facet ost1 $LCTL set_param fail_loc=0
23377         umount_client $MOUNT || error "umount failed"
23378         mount_client $MOUNT || error "mount failed"
23379         stop ost1 || error "cannot stop ost1"
23380         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23381 }
23382 run_test 232b "failed data version lock should not block umount"
23383
23384 test_233a() {
23385         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23386                 skip "Need MDS version at least 2.3.64"
23387         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23388
23389         local fid=$($LFS path2fid $MOUNT)
23390
23391         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23392                 error "cannot access $MOUNT using its FID '$fid'"
23393 }
23394 run_test 233a "checking that OBF of the FS root succeeds"
23395
23396 test_233b() {
23397         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23398                 skip "Need MDS version at least 2.5.90"
23399         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23400
23401         local fid=$($LFS path2fid $MOUNT/.lustre)
23402
23403         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23404                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23405
23406         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23407         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23408                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23409 }
23410 run_test 233b "checking that OBF of the FS .lustre succeeds"
23411
23412 test_234() {
23413         local p="$TMP/sanityN-$TESTNAME.parameters"
23414         save_lustre_params client "llite.*.xattr_cache" > $p
23415         lctl set_param llite.*.xattr_cache 1 ||
23416                 skip_env "xattr cache is not supported"
23417
23418         mkdir -p $DIR/$tdir || error "mkdir failed"
23419         touch $DIR/$tdir/$tfile || error "touch failed"
23420         # OBD_FAIL_LLITE_XATTR_ENOMEM
23421         $LCTL set_param fail_loc=0x1405
23422         getfattr -n user.attr $DIR/$tdir/$tfile &&
23423                 error "getfattr should have failed with ENOMEM"
23424         $LCTL set_param fail_loc=0x0
23425         rm -rf $DIR/$tdir
23426
23427         restore_lustre_params < $p
23428         rm -f $p
23429 }
23430 run_test 234 "xattr cache should not crash on ENOMEM"
23431
23432 test_235() {
23433         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23434                 skip "Need MDS version at least 2.4.52"
23435
23436         flock_deadlock $DIR/$tfile
23437         local RC=$?
23438         case $RC in
23439                 0)
23440                 ;;
23441                 124) error "process hangs on a deadlock"
23442                 ;;
23443                 *) error "error executing flock_deadlock $DIR/$tfile"
23444                 ;;
23445         esac
23446 }
23447 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23448
23449 #LU-2935
23450 test_236() {
23451         check_swap_layouts_support
23452
23453         local ref1=/etc/passwd
23454         local ref2=/etc/group
23455         local file1=$DIR/$tdir/f1
23456         local file2=$DIR/$tdir/f2
23457
23458         test_mkdir -c1 $DIR/$tdir
23459         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23460         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23461         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23462         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23463         local fd=$(free_fd)
23464         local cmd="exec $fd<>$file2"
23465         eval $cmd
23466         rm $file2
23467         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23468                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23469         cmd="exec $fd>&-"
23470         eval $cmd
23471         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23472
23473         #cleanup
23474         rm -rf $DIR/$tdir
23475 }
23476 run_test 236 "Layout swap on open unlinked file"
23477
23478 # LU-4659 linkea consistency
23479 test_238() {
23480         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23481                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23482                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23483                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23484
23485         touch $DIR/$tfile
23486         ln $DIR/$tfile $DIR/$tfile.lnk
23487         touch $DIR/$tfile.new
23488         mv $DIR/$tfile.new $DIR/$tfile
23489         local fid1=$($LFS path2fid $DIR/$tfile)
23490         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23491         local path1=$($LFS fid2path $FSNAME "$fid1")
23492         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23493         local path2=$($LFS fid2path $FSNAME "$fid2")
23494         [ $tfile.lnk == $path2 ] ||
23495                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23496         rm -f $DIR/$tfile*
23497 }
23498 run_test 238 "Verify linkea consistency"
23499
23500 test_239A() { # was test_239
23501         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23502                 skip "Need MDS version at least 2.5.60"
23503
23504         local list=$(comma_list $(mdts_nodes))
23505
23506         mkdir -p $DIR/$tdir
23507         createmany -o $DIR/$tdir/f- 5000
23508         unlinkmany $DIR/$tdir/f- 5000
23509         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23510                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23511         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23512                         osp.*MDT*.sync_in_flight" | calc_sum)
23513         [ "$changes" -eq 0 ] || error "$changes not synced"
23514 }
23515 run_test 239A "osp_sync test"
23516
23517 test_239a() { #LU-5297
23518         remote_mds_nodsh && skip "remote MDS with nodsh"
23519
23520         touch $DIR/$tfile
23521         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23522         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23523         chgrp $RUNAS_GID $DIR/$tfile
23524         wait_delete_completed
23525 }
23526 run_test 239a "process invalid osp sync record correctly"
23527
23528 test_239b() { #LU-5297
23529         remote_mds_nodsh && skip "remote MDS with nodsh"
23530
23531         touch $DIR/$tfile1
23532         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23533         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23534         chgrp $RUNAS_GID $DIR/$tfile1
23535         wait_delete_completed
23536         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23537         touch $DIR/$tfile2
23538         chgrp $RUNAS_GID $DIR/$tfile2
23539         wait_delete_completed
23540 }
23541 run_test 239b "process osp sync record with ENOMEM error correctly"
23542
23543 test_240() {
23544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23545         remote_mds_nodsh && skip "remote MDS with nodsh"
23546
23547         mkdir -p $DIR/$tdir
23548
23549         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23550                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23551         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23552                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23553
23554         umount_client $MOUNT || error "umount failed"
23555         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23556         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23557         mount_client $MOUNT || error "failed to mount client"
23558
23559         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23560         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23561 }
23562 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23563
23564 test_241_bio() {
23565         local count=$1
23566         local bsize=$2
23567
23568         for LOOP in $(seq $count); do
23569                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23570                 cancel_lru_locks $OSC || true
23571         done
23572 }
23573
23574 test_241_dio() {
23575         local count=$1
23576         local bsize=$2
23577
23578         for LOOP in $(seq $1); do
23579                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23580                         2>/dev/null
23581         done
23582 }
23583
23584 test_241a() { # was test_241
23585         local bsize=$PAGE_SIZE
23586
23587         (( bsize < 40960 )) && bsize=40960
23588         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23589         ls -la $DIR/$tfile
23590         cancel_lru_locks $OSC
23591         test_241_bio 1000 $bsize &
23592         PID=$!
23593         test_241_dio 1000 $bsize
23594         wait $PID
23595 }
23596 run_test 241a "bio vs dio"
23597
23598 test_241b() {
23599         local bsize=$PAGE_SIZE
23600
23601         (( bsize < 40960 )) && bsize=40960
23602         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23603         ls -la $DIR/$tfile
23604         test_241_dio 1000 $bsize &
23605         PID=$!
23606         test_241_dio 1000 $bsize
23607         wait $PID
23608 }
23609 run_test 241b "dio vs dio"
23610
23611 test_242() {
23612         remote_mds_nodsh && skip "remote MDS with nodsh"
23613
23614         mkdir_on_mdt0 $DIR/$tdir
23615         touch $DIR/$tdir/$tfile
23616
23617         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23618         do_facet mds1 lctl set_param fail_loc=0x105
23619         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23620
23621         do_facet mds1 lctl set_param fail_loc=0
23622         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23623 }
23624 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23625
23626 test_243()
23627 {
23628         test_mkdir $DIR/$tdir
23629         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23630 }
23631 run_test 243 "various group lock tests"
23632
23633 test_244a()
23634 {
23635         test_mkdir $DIR/$tdir
23636         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23637         sendfile_grouplock $DIR/$tdir/$tfile || \
23638                 error "sendfile+grouplock failed"
23639         rm -rf $DIR/$tdir
23640 }
23641 run_test 244a "sendfile with group lock tests"
23642
23643 test_244b()
23644 {
23645         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23646
23647         local threads=50
23648         local size=$((1024*1024))
23649
23650         test_mkdir $DIR/$tdir
23651         for i in $(seq 1 $threads); do
23652                 local file=$DIR/$tdir/file_$((i / 10))
23653                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23654                 local pids[$i]=$!
23655         done
23656         for i in $(seq 1 $threads); do
23657                 wait ${pids[$i]}
23658         done
23659 }
23660 run_test 244b "multi-threaded write with group lock"
23661
23662 test_245a() {
23663         local flagname="multi_mod_rpcs"
23664         local connect_data_name="max_mod_rpcs"
23665         local out
23666
23667         # check if multiple modify RPCs flag is set
23668         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23669                 grep "connect_flags:")
23670         echo "$out"
23671
23672         echo "$out" | grep -qw $flagname
23673         if [ $? -ne 0 ]; then
23674                 echo "connect flag $flagname is not set"
23675                 return
23676         fi
23677
23678         # check if multiple modify RPCs data is set
23679         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23680         echo "$out"
23681
23682         echo "$out" | grep -qw $connect_data_name ||
23683                 error "import should have connect data $connect_data_name"
23684 }
23685 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23686
23687 test_245b() {
23688         local flagname="multi_mod_rpcs"
23689         local connect_data_name="max_mod_rpcs"
23690         local out
23691
23692         remote_mds_nodsh && skip "remote MDS with nodsh"
23693         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23694
23695         # check if multiple modify RPCs flag is set
23696         out=$(do_facet mds1 \
23697               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23698               grep "connect_flags:")
23699         echo "$out"
23700
23701         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23702
23703         # check if multiple modify RPCs data is set
23704         out=$(do_facet mds1 \
23705               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23706
23707         [[ "$out" =~ $connect_data_name ]] ||
23708                 {
23709                         echo "$out"
23710                         error "missing connect data $connect_data_name"
23711                 }
23712 }
23713 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23714
23715 cleanup_247() {
23716         local submount=$1
23717
23718         trap 0
23719         umount_client $submount
23720         rmdir $submount
23721 }
23722
23723 test_247a() {
23724         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23725                 grep -q subtree ||
23726                 skip_env "Fileset feature is not supported"
23727
23728         local submount=${MOUNT}_$tdir
23729
23730         mkdir $MOUNT/$tdir
23731         mkdir -p $submount || error "mkdir $submount failed"
23732         FILESET="$FILESET/$tdir" mount_client $submount ||
23733                 error "mount $submount failed"
23734         trap "cleanup_247 $submount" EXIT
23735         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23736         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23737                 error "read $MOUNT/$tdir/$tfile failed"
23738         cleanup_247 $submount
23739 }
23740 run_test 247a "mount subdir as fileset"
23741
23742 test_247b() {
23743         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23744                 skip_env "Fileset feature is not supported"
23745
23746         local submount=${MOUNT}_$tdir
23747
23748         rm -rf $MOUNT/$tdir
23749         mkdir -p $submount || error "mkdir $submount failed"
23750         SKIP_FILESET=1
23751         FILESET="$FILESET/$tdir" mount_client $submount &&
23752                 error "mount $submount should fail"
23753         rmdir $submount
23754 }
23755 run_test 247b "mount subdir that dose not exist"
23756
23757 test_247c() {
23758         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23759                 skip_env "Fileset feature is not supported"
23760
23761         local submount=${MOUNT}_$tdir
23762
23763         mkdir -p $MOUNT/$tdir/dir1
23764         mkdir -p $submount || error "mkdir $submount failed"
23765         trap "cleanup_247 $submount" EXIT
23766         FILESET="$FILESET/$tdir" mount_client $submount ||
23767                 error "mount $submount failed"
23768         local fid=$($LFS path2fid $MOUNT/)
23769         $LFS fid2path $submount $fid && error "fid2path should fail"
23770         cleanup_247 $submount
23771 }
23772 run_test 247c "running fid2path outside subdirectory root"
23773
23774 test_247d() {
23775         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23776                 skip "Fileset feature is not supported"
23777
23778         local submount=${MOUNT}_$tdir
23779
23780         mkdir -p $MOUNT/$tdir/dir1
23781         mkdir -p $submount || error "mkdir $submount failed"
23782         FILESET="$FILESET/$tdir" mount_client $submount ||
23783                 error "mount $submount failed"
23784         trap "cleanup_247 $submount" EXIT
23785
23786         local td=$submount/dir1
23787         local fid=$($LFS path2fid $td)
23788         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23789
23790         # check that we get the same pathname back
23791         local rootpath
23792         local found
23793         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23794                 echo "$rootpath $fid"
23795                 found=$($LFS fid2path $rootpath "$fid")
23796                 [ -n "$found" ] || error "fid2path should succeed"
23797                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23798         done
23799         # check wrong root path format
23800         rootpath=$submount"_wrong"
23801         found=$($LFS fid2path $rootpath "$fid")
23802         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23803
23804         cleanup_247 $submount
23805 }
23806 run_test 247d "running fid2path inside subdirectory root"
23807
23808 # LU-8037
23809 test_247e() {
23810         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23811                 grep -q subtree ||
23812                 skip "Fileset feature is not supported"
23813
23814         local submount=${MOUNT}_$tdir
23815
23816         mkdir $MOUNT/$tdir
23817         mkdir -p $submount || error "mkdir $submount failed"
23818         FILESET="$FILESET/.." mount_client $submount &&
23819                 error "mount $submount should fail"
23820         rmdir $submount
23821 }
23822 run_test 247e "mount .. as fileset"
23823
23824 test_247f() {
23825         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23826         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23827                 skip "Need at least version 2.14.50.162"
23828         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23829                 skip "Fileset feature is not supported"
23830
23831         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23832         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23833                 error "mkdir remote failed"
23834         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23835                 error "mkdir remote/subdir failed"
23836         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23837                 error "mkdir striped failed"
23838         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23839
23840         local submount=${MOUNT}_$tdir
23841
23842         mkdir -p $submount || error "mkdir $submount failed"
23843         stack_trap "rmdir $submount"
23844
23845         local dir
23846         local fileset=$FILESET
23847         local mdts=$(comma_list $(mdts_nodes))
23848
23849         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23850         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23851                 $tdir/striped/subdir $tdir/striped/.; do
23852                 FILESET="$fileset/$dir" mount_client $submount ||
23853                         error "mount $dir failed"
23854                 umount_client $submount
23855         done
23856 }
23857 run_test 247f "mount striped or remote directory as fileset"
23858
23859 test_subdir_mount_lock()
23860 {
23861         local testdir=$1
23862         local submount=${MOUNT}_$(basename $testdir)
23863
23864         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23865
23866         mkdir -p $submount || error "mkdir $submount failed"
23867         stack_trap "rmdir $submount"
23868
23869         FILESET="$fileset/$testdir" mount_client $submount ||
23870                 error "mount $FILESET failed"
23871         stack_trap "umount $submount"
23872
23873         local mdts=$(comma_list $(mdts_nodes))
23874
23875         local nrpcs
23876
23877         stat $submount > /dev/null || error "stat $submount failed"
23878         cancel_lru_locks $MDC
23879         stat $submount > /dev/null || error "stat $submount failed"
23880         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23881         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23882         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23883         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23884                 awk '/getattr/ {sum += $2} END {print sum}')
23885
23886         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23887 }
23888
23889 test_247g() {
23890         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23891
23892         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23893                 error "mkdir $tdir failed"
23894         test_subdir_mount_lock $tdir
23895 }
23896 run_test 247g "striped directory submount revalidate ROOT from cache"
23897
23898 test_247h() {
23899         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23900         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23901                 skip "Need MDS version at least 2.15.51"
23902
23903         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23904         test_subdir_mount_lock $tdir
23905         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23906         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23907                 error "mkdir $tdir.1 failed"
23908         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23909 }
23910 run_test 247h "remote directory submount revalidate ROOT from cache"
23911
23912 test_248a() {
23913         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23914         [ -z "$fast_read_sav" ] && skip "no fast read support"
23915
23916         # create a large file for fast read verification
23917         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23918
23919         # make sure the file is created correctly
23920         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23921                 { rm -f $DIR/$tfile; skip "file creation error"; }
23922
23923         echo "Test 1: verify that fast read is 4 times faster on cache read"
23924
23925         # small read with fast read enabled
23926         $LCTL set_param -n llite.*.fast_read=1
23927         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23928                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23929                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23930         # small read with fast read disabled
23931         $LCTL set_param -n llite.*.fast_read=0
23932         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23933                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23934                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23935
23936         # verify that fast read is 4 times faster for cache read
23937         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23938                 error_not_in_vm "fast read was not 4 times faster: " \
23939                            "$t_fast vs $t_slow"
23940
23941         echo "Test 2: verify the performance between big and small read"
23942         $LCTL set_param -n llite.*.fast_read=1
23943
23944         # 1k non-cache read
23945         cancel_lru_locks osc
23946         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23947                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23948                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23949
23950         # 1M non-cache read
23951         cancel_lru_locks osc
23952         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23953                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23954                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23955
23956         # verify that big IO is not 4 times faster than small IO
23957         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23958                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23959
23960         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23961         rm -f $DIR/$tfile
23962 }
23963 run_test 248a "fast read verification"
23964
23965 test_248b() {
23966         # Default short_io_bytes=16384, try both smaller and larger sizes.
23967         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23968         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23969         echo "bs=53248 count=113 normal buffered write"
23970         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23971                 error "dd of initial data file failed"
23972         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23973
23974         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23975         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23976                 error "dd with sync normal writes failed"
23977         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23978
23979         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23980         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23981                 error "dd with sync small writes failed"
23982         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23983
23984         cancel_lru_locks osc
23985
23986         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23987         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23988         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23989         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23990                 iflag=direct || error "dd with O_DIRECT small read failed"
23991         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23992         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23993                 error "compare $TMP/$tfile.1 failed"
23994
23995         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23996         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23997
23998         # just to see what the maximum tunable value is, and test parsing
23999         echo "test invalid parameter 2MB"
24000         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
24001                 error "too-large short_io_bytes allowed"
24002         echo "test maximum parameter 512KB"
24003         # if we can set a larger short_io_bytes, run test regardless of version
24004         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
24005                 # older clients may not allow setting it this large, that's OK
24006                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
24007                         skip "Need at least client version 2.13.50"
24008                 error "medium short_io_bytes failed"
24009         fi
24010         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
24011         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
24012
24013         echo "test large parameter 64KB"
24014         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
24015         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
24016
24017         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
24018         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
24019                 error "dd with sync large writes failed"
24020         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
24021
24022         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
24023         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
24024         num=$((113 * 4096 / PAGE_SIZE))
24025         echo "bs=$size count=$num oflag=direct large write $tfile.3"
24026         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
24027                 error "dd with O_DIRECT large writes failed"
24028         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
24029                 error "compare $DIR/$tfile.3 failed"
24030
24031         cancel_lru_locks osc
24032
24033         echo "bs=$size count=$num iflag=direct large read $tfile.2"
24034         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
24035                 error "dd with O_DIRECT large read failed"
24036         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
24037                 error "compare $TMP/$tfile.2 failed"
24038
24039         echo "bs=$size count=$num iflag=direct large read $tfile.3"
24040         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
24041                 error "dd with O_DIRECT large read failed"
24042         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
24043                 error "compare $TMP/$tfile.3 failed"
24044 }
24045 run_test 248b "test short_io read and write for both small and large sizes"
24046
24047 test_248c() {
24048         $LCTL set_param llite.*.read_ahead_stats=c
24049         # This test compares whole file readahead to non-whole file readahead
24050         # The performance should be consistently slightly faster for whole file,
24051         # and the bug caused whole file readahead to be 80-100x slower, but to
24052         # account for possible test system lag, we require whole file to be
24053         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
24054         # test
24055         local time1
24056         local time2
24057         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
24058         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
24059         counter=0
24060
24061         while [ $counter -lt 3 ]; do
24062                 # Increment the counter
24063                 ((counter++))
24064
24065                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
24066                 rm -f $DIR/$tfile
24067                 touch $DIR/$tfile || error "(0) failed to create file"
24068                 # 64 MiB
24069                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
24070                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
24071                 echo "whole file readahead of 64 MiB took $time1 seconds"
24072                 $LCTL get_param llite.*.read_ahead_stats
24073
24074                 $LCTL set_param llite.*.read_ahead_stats=c
24075                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
24076                 rm -f $DIR/$tfile
24077                 touch $DIR/$tfile || error "(2) failed to create file"
24078                 # 64 MiB
24079                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
24080                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
24081                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
24082                 $LCTL get_param llite.*.read_ahead_stats
24083
24084                 # Check if time1 is not more than 1.5 times2
24085                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
24086
24087                 if [[ $timecheck -eq 1 ]]; then
24088                         echo "Test passed on attempt $counter"
24089                         # Exit the loop
24090                         counter=4
24091                 else
24092                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
24093                 fi
24094         done
24095         if [ $counter -eq 3 ]; then
24096                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
24097         fi
24098
24099 }
24100 run_test 248c "verify whole file read behavior"
24101
24102 test_249() { # LU-7890
24103         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
24104                 skip "Need at least version 2.8.54"
24105
24106         rm -f $DIR/$tfile
24107         $LFS setstripe -c 1 $DIR/$tfile
24108         # Offset 2T == 4k * 512M
24109         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
24110                 error "dd to 2T offset failed"
24111 }
24112 run_test 249 "Write above 2T file size"
24113
24114 test_250() {
24115         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
24116          && skip "no 16TB file size limit on ZFS"
24117
24118         $LFS setstripe -c 1 $DIR/$tfile
24119         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
24120         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
24121         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
24122         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
24123                 conv=notrunc,fsync && error "append succeeded"
24124         return 0
24125 }
24126 run_test 250 "Write above 16T limit"
24127
24128 test_251a() {
24129         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
24130
24131         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
24132         #Skip once - writing the first stripe will succeed
24133         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24134         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
24135                 error "short write happened"
24136
24137         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24138         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
24139                 error "short read happened"
24140
24141         rm -f $DIR/$tfile
24142 }
24143 run_test 251a "Handling short read and write correctly"
24144
24145 test_251b() {
24146         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24147                 error "write $tfile failed"
24148
24149         sleep 2 && echo 12345 >> $DIR/$tfile &
24150
24151         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24152         $LCTL set_param fail_loc=0x1431 fail_val=5
24153         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24154         # 5 seconds, read 10 bytes, the short read should
24155         # report:
24156         #                start ->+ read_len -> offset_after_read read_count
24157         #     short read: 4096 ->+ 10 -> 4096 0
24158         # not:
24159         #     short read: 4096 ->+ 10 -> 4102 0
24160         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24161                         awk '/short read/ { print $7 }')
24162         (( off == 4096 )) ||
24163                 error "short read should set offset at 4096, not $off"
24164 }
24165 run_test 251b "short read restore offset correctly"
24166
24167 test_252() {
24168         remote_mds_nodsh && skip "remote MDS with nodsh"
24169         remote_ost_nodsh && skip "remote OST with nodsh"
24170         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24171                 skip_env "ldiskfs only test"
24172         fi
24173
24174         local tgt
24175         local dev
24176         local out
24177         local uuid
24178         local num
24179         local gen
24180
24181         # check lr_reader on OST0000
24182         tgt=ost1
24183         dev=$(facet_device $tgt)
24184         out=$(do_facet $tgt $LR_READER $dev)
24185         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24186         echo "$out"
24187         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24188         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24189                 error "Invalid uuid returned by $LR_READER on target $tgt"
24190         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24191
24192         # check lr_reader -c on MDT0000
24193         tgt=mds1
24194         dev=$(facet_device $tgt)
24195         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24196                 skip "$LR_READER does not support additional options"
24197         fi
24198         out=$(do_facet $tgt $LR_READER -c $dev)
24199         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24200         echo "$out"
24201         num=$(echo "$out" | grep -c "mdtlov")
24202         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24203                 error "Invalid number of mdtlov clients returned by $LR_READER"
24204         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24205
24206         # check lr_reader -cr on MDT0000
24207         out=$(do_facet $tgt $LR_READER -cr $dev)
24208         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24209         echo "$out"
24210         echo "$out" | grep -q "^reply_data:$" ||
24211                 error "$LR_READER should have returned 'reply_data' section"
24212         num=$(echo "$out" | grep -c "client_generation")
24213         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24214 }
24215 run_test 252 "check lr_reader tool"
24216
24217 test_253() {
24218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24219         remote_mds_nodsh && skip "remote MDS with nodsh"
24220         remote_mgs_nodsh && skip "remote MGS with nodsh"
24221         check_set_fallocate_or_skip
24222
24223         local ostidx=0
24224         local rc=0
24225         local ost_name=$(ostname_from_index $ostidx)
24226
24227         # on the mdt's osc
24228         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24229         do_facet $SINGLEMDS $LCTL get_param -n \
24230                 osp.$mdtosc_proc1.reserved_mb_high ||
24231                 skip  "remote MDS does not support reserved_mb_high"
24232
24233         rm -rf $DIR/$tdir
24234         wait_mds_ost_sync
24235         wait_delete_completed
24236         mkdir $DIR/$tdir
24237         stack_trap "rm -rf $DIR/$tdir"
24238
24239         pool_add $TESTNAME || error "Pool creation failed"
24240         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24241
24242         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24243                 error "Setstripe failed"
24244
24245         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24246
24247         local wms=$(ost_watermarks_get $ostidx)
24248
24249         ost_watermarks_set $ostidx 60 50
24250         stack_trap "ost_watermarks_set $ostidx $wms"
24251
24252         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24253         local size=$((free_kb * 1024))
24254
24255         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24256                 error "fallocate failed"
24257         sleep_maxage
24258
24259         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24260                         osp.$mdtosc_proc1.prealloc_status)
24261         echo "prealloc_status $oa_status"
24262
24263         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24264                 error "File creation should fail"
24265
24266         #object allocation was stopped, but we still able to append files
24267         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24268                 oflag=append || error "Append failed"
24269
24270         rm -f $DIR/$tdir/$tfile.0
24271         rm -f $DIR/$tdir/fill_ost$ostidx
24272
24273         wait_delete_completed
24274         sleep_maxage
24275
24276         for i in $(seq 10 12); do
24277                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24278                         2>/dev/null || error "File creation failed after rm"
24279         done
24280
24281         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24282                         osp.$mdtosc_proc1.prealloc_status)
24283         echo "prealloc_status $oa_status"
24284
24285         if (( oa_status != 0 )); then
24286                 error "Object allocation still disable after rm"
24287         fi
24288 }
24289 run_test 253 "Check object allocation limit"
24290
24291 test_254() {
24292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24293         remote_mds_nodsh && skip "remote MDS with nodsh"
24294
24295         local mdt=$(facet_svc $SINGLEMDS)
24296
24297         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24298                 skip "MDS does not support changelog_size"
24299
24300         local cl_user
24301
24302         changelog_register || error "changelog_register failed"
24303
24304         changelog_clear 0 || error "changelog_clear failed"
24305
24306         local size1=$(do_facet $SINGLEMDS \
24307                       $LCTL get_param -n mdd.$mdt.changelog_size)
24308         echo "Changelog size $size1"
24309
24310         rm -rf $DIR/$tdir
24311         $LFS mkdir -i 0 $DIR/$tdir
24312         # change something
24313         mkdir -p $DIR/$tdir/pics/2008/zachy
24314         touch $DIR/$tdir/pics/2008/zachy/timestamp
24315         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24316         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24317         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24318         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24319         rm $DIR/$tdir/pics/desktop.jpg
24320
24321         local size2=$(do_facet $SINGLEMDS \
24322                       $LCTL get_param -n mdd.$mdt.changelog_size)
24323         echo "Changelog size after work $size2"
24324
24325         (( $size2 > $size1 )) ||
24326                 error "new Changelog size=$size2 less than old size=$size1"
24327 }
24328 run_test 254 "Check changelog size"
24329
24330 ladvise_no_type()
24331 {
24332         local type=$1
24333         local file=$2
24334
24335         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24336                 awk -F: '{print $2}' | grep $type > /dev/null
24337         if [ $? -ne 0 ]; then
24338                 return 0
24339         fi
24340         return 1
24341 }
24342
24343 ladvise_no_ioctl()
24344 {
24345         local file=$1
24346
24347         lfs ladvise -a willread $file > /dev/null 2>&1
24348         if [ $? -eq 0 ]; then
24349                 return 1
24350         fi
24351
24352         lfs ladvise -a willread $file 2>&1 |
24353                 grep "Inappropriate ioctl for device" > /dev/null
24354         if [ $? -eq 0 ]; then
24355                 return 0
24356         fi
24357         return 1
24358 }
24359
24360 percent() {
24361         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24362 }
24363
24364 # run a random read IO workload
24365 # usage: random_read_iops <filename> <filesize> <iosize>
24366 random_read_iops() {
24367         local file=$1
24368         local fsize=$2
24369         local iosize=${3:-4096}
24370
24371         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24372                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24373 }
24374
24375 drop_file_oss_cache() {
24376         local file="$1"
24377         local nodes="$2"
24378
24379         $LFS ladvise -a dontneed $file 2>/dev/null ||
24380                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24381 }
24382
24383 ladvise_willread_performance()
24384 {
24385         local repeat=10
24386         local average_origin=0
24387         local average_cache=0
24388         local average_ladvise=0
24389
24390         for ((i = 1; i <= $repeat; i++)); do
24391                 echo "Iter $i/$repeat: reading without willread hint"
24392                 cancel_lru_locks osc
24393                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24394                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24395                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24396                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24397
24398                 cancel_lru_locks osc
24399                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24400                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24401                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24402
24403                 cancel_lru_locks osc
24404                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24405                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24406                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24407                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24408                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24409         done
24410         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24411         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24412         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24413
24414         speedup_cache=$(percent $average_cache $average_origin)
24415         speedup_ladvise=$(percent $average_ladvise $average_origin)
24416
24417         echo "Average uncached read: $average_origin"
24418         echo "Average speedup with OSS cached read:" \
24419                 "$average_cache = +$speedup_cache%"
24420         echo "Average speedup with ladvise willread:" \
24421                 "$average_ladvise = +$speedup_ladvise%"
24422
24423         local lowest_speedup=20
24424         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24425                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24426                      "got $speedup_cache%. Skipping ladvise willread check."
24427                 return 0
24428         fi
24429
24430         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24431         # it is still good to run until then to exercise 'ladvise willread'
24432         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24433                 [ "$ost1_FSTYPE" = "zfs" ] &&
24434                 echo "osd-zfs does not support dontneed or drop_caches" &&
24435                 return 0
24436
24437         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24438         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24439                 error_not_in_vm "Speedup with willread is less than " \
24440                         "$lowest_speedup%, got $speedup_ladvise%"
24441 }
24442
24443 test_255a() {
24444         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24445                 skip "lustre < 2.8.54 does not support ladvise "
24446         remote_ost_nodsh && skip "remote OST with nodsh"
24447
24448         stack_trap "rm -f $DIR/$tfile"
24449         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24450
24451         ladvise_no_type willread $DIR/$tfile &&
24452                 skip "willread ladvise is not supported"
24453
24454         ladvise_no_ioctl $DIR/$tfile &&
24455                 skip "ladvise ioctl is not supported"
24456
24457         local size_mb=100
24458         local size=$((size_mb * 1048576))
24459         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24460                 error "dd to $DIR/$tfile failed"
24461
24462         lfs ladvise -a willread $DIR/$tfile ||
24463                 error "Ladvise failed with no range argument"
24464
24465         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24466                 error "Ladvise failed with no -l or -e argument"
24467
24468         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24469                 error "Ladvise failed with only -e argument"
24470
24471         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24472                 error "Ladvise failed with only -l argument"
24473
24474         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24475                 error "End offset should not be smaller than start offset"
24476
24477         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24478                 error "End offset should not be equal to start offset"
24479
24480         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24481                 error "Ladvise failed with overflowing -s argument"
24482
24483         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24484                 error "Ladvise failed with overflowing -e argument"
24485
24486         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24487                 error "Ladvise failed with overflowing -l argument"
24488
24489         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24490                 error "Ladvise succeeded with conflicting -l and -e arguments"
24491
24492         echo "Synchronous ladvise should wait"
24493         local delay=8
24494 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24495         do_nodes $(comma_list $(osts_nodes)) \
24496                 $LCTL set_param fail_val=$delay fail_loc=0x237
24497         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24498                 $LCTL set_param fail_loc=0"
24499
24500         local start_ts=$SECONDS
24501         lfs ladvise -a willread $DIR/$tfile ||
24502                 error "Ladvise failed with no range argument"
24503         local end_ts=$SECONDS
24504         local inteval_ts=$((end_ts - start_ts))
24505
24506         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24507                 error "Synchronous advice didn't wait reply"
24508         fi
24509
24510         echo "Asynchronous ladvise shouldn't wait"
24511         local start_ts=$SECONDS
24512         lfs ladvise -a willread -b $DIR/$tfile ||
24513                 error "Ladvise failed with no range argument"
24514         local end_ts=$SECONDS
24515         local inteval_ts=$((end_ts - start_ts))
24516
24517         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24518                 error "Asynchronous advice blocked"
24519         fi
24520
24521         ladvise_willread_performance
24522 }
24523 run_test 255a "check 'lfs ladvise -a willread'"
24524
24525 facet_meminfo() {
24526         local facet=$1
24527         local info=$2
24528
24529         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24530 }
24531
24532 test_255b() {
24533         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24534                 skip "lustre < 2.8.54 does not support ladvise "
24535         remote_ost_nodsh && skip "remote OST with nodsh"
24536
24537         stack_trap "rm -f $DIR/$tfile"
24538         lfs setstripe -c 1 -i 0 $DIR/$tfile
24539
24540         ladvise_no_type dontneed $DIR/$tfile &&
24541                 skip "dontneed ladvise is not supported"
24542
24543         ladvise_no_ioctl $DIR/$tfile &&
24544                 skip "ladvise ioctl is not supported"
24545
24546         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24547                 [ "$ost1_FSTYPE" = "zfs" ] &&
24548                 skip "zfs-osd does not support 'ladvise dontneed'"
24549
24550         local size_mb=100
24551         local size=$((size_mb * 1048576))
24552         # In order to prevent disturbance of other processes, only check 3/4
24553         # of the memory usage
24554         local kibibytes=$((size_mb * 1024 * 3 / 4))
24555
24556         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24557                 error "dd to $DIR/$tfile failed"
24558
24559         #force write to complete before dropping OST cache & checking memory
24560         sync
24561
24562         local total=$(facet_meminfo ost1 MemTotal)
24563         echo "Total memory: $total KiB"
24564
24565         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24566         local before_read=$(facet_meminfo ost1 Cached)
24567         echo "Cache used before read: $before_read KiB"
24568
24569         lfs ladvise -a willread $DIR/$tfile ||
24570                 error "Ladvise willread failed"
24571         local after_read=$(facet_meminfo ost1 Cached)
24572         echo "Cache used after read: $after_read KiB"
24573
24574         lfs ladvise -a dontneed $DIR/$tfile ||
24575                 error "Ladvise dontneed again failed"
24576         local no_read=$(facet_meminfo ost1 Cached)
24577         echo "Cache used after dontneed ladvise: $no_read KiB"
24578
24579         if [ $total -lt $((before_read + kibibytes)) ]; then
24580                 echo "Memory is too small, abort checking"
24581                 return 0
24582         fi
24583
24584         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24585                 error "Ladvise willread should use more memory" \
24586                         "than $kibibytes KiB"
24587         fi
24588
24589         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24590                 error "Ladvise dontneed should release more memory" \
24591                         "than $kibibytes KiB"
24592         fi
24593 }
24594 run_test 255b "check 'lfs ladvise -a dontneed'"
24595
24596 test_255c() {
24597         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24598                 skip "lustre < 2.10.50 does not support lockahead"
24599
24600         local ost1_imp=$(get_osc_import_name client ost1)
24601         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24602                          cut -d'.' -f2)
24603         local count
24604         local new_count
24605         local difference
24606         local i
24607         local rc
24608
24609         test_mkdir -p $DIR/$tdir
24610         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24611
24612         #test 10 returns only success/failure
24613         i=10
24614         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24615         rc=$?
24616         if [ $rc -eq 255 ]; then
24617                 error "Ladvise test${i} failed, ${rc}"
24618         fi
24619
24620         #test 11 counts lock enqueue requests, all others count new locks
24621         i=11
24622         count=$(do_facet ost1 \
24623                 $LCTL get_param -n ost.OSS.ost.stats)
24624         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24625
24626         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24627         rc=$?
24628         if [ $rc -eq 255 ]; then
24629                 error "Ladvise test${i} failed, ${rc}"
24630         fi
24631
24632         new_count=$(do_facet ost1 \
24633                 $LCTL get_param -n ost.OSS.ost.stats)
24634         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24635                    awk '{ print $2 }')
24636
24637         difference="$((new_count - count))"
24638         if [ $difference -ne $rc ]; then
24639                 error "Ladvise test${i}, bad enqueue count, returned " \
24640                       "${rc}, actual ${difference}"
24641         fi
24642
24643         for i in $(seq 12 21); do
24644                 # If we do not do this, we run the risk of having too many
24645                 # locks and starting lock cancellation while we are checking
24646                 # lock counts.
24647                 cancel_lru_locks osc
24648
24649                 count=$($LCTL get_param -n \
24650                        ldlm.namespaces.$imp_name.lock_unused_count)
24651
24652                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24653                 rc=$?
24654                 if [ $rc -eq 255 ]; then
24655                         error "Ladvise test ${i} failed, ${rc}"
24656                 fi
24657
24658                 new_count=$($LCTL get_param -n \
24659                        ldlm.namespaces.$imp_name.lock_unused_count)
24660                 difference="$((new_count - count))"
24661
24662                 # Test 15 output is divided by 100 to map down to valid return
24663                 if [ $i -eq 15 ]; then
24664                         rc="$((rc * 100))"
24665                 fi
24666
24667                 if [ $difference -ne $rc ]; then
24668                         error "Ladvise test ${i}, bad lock count, returned " \
24669                               "${rc}, actual ${difference}"
24670                 fi
24671         done
24672
24673         #test 22 returns only success/failure
24674         i=22
24675         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24676         rc=$?
24677         if [ $rc -eq 255 ]; then
24678                 error "Ladvise test${i} failed, ${rc}"
24679         fi
24680 }
24681 run_test 255c "suite of ladvise lockahead tests"
24682
24683 test_256() {
24684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24685         remote_mds_nodsh && skip "remote MDS with nodsh"
24686         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24687         changelog_users $SINGLEMDS | grep "^cl" &&
24688                 skip "active changelog user"
24689
24690         local cl_user
24691         local cat_sl
24692         local mdt_dev
24693
24694         mdt_dev=$(facet_device $SINGLEMDS)
24695         echo $mdt_dev
24696
24697         changelog_register || error "changelog_register failed"
24698
24699         rm -rf $DIR/$tdir
24700         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24701
24702         changelog_clear 0 || error "changelog_clear failed"
24703
24704         # change something
24705         touch $DIR/$tdir/{1..10}
24706
24707         # stop the MDT
24708         stop $SINGLEMDS || error "Fail to stop MDT"
24709
24710         # remount the MDT
24711         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24712                 error "Fail to start MDT"
24713
24714         #after mount new plainllog is used
24715         touch $DIR/$tdir/{11..19}
24716         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24717         stack_trap "rm -f $tmpfile"
24718         cat_sl=$(do_facet $SINGLEMDS "sync; \
24719                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24720                  llog_reader $tmpfile | grep -c type=1064553b")
24721         do_facet $SINGLEMDS llog_reader $tmpfile
24722
24723         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24724
24725         changelog_clear 0 || error "changelog_clear failed"
24726
24727         cat_sl=$(do_facet $SINGLEMDS "sync; \
24728                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24729                  llog_reader $tmpfile | grep -c type=1064553b")
24730
24731         if (( cat_sl == 2 )); then
24732                 error "Empty plain llog was not deleted from changelog catalog"
24733         elif (( cat_sl != 1 )); then
24734                 error "Active plain llog shouldn't be deleted from catalog"
24735         fi
24736 }
24737 run_test 256 "Check llog delete for empty and not full state"
24738
24739 test_257() {
24740         remote_mds_nodsh && skip "remote MDS with nodsh"
24741         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24742                 skip "Need MDS version at least 2.8.55"
24743
24744         test_mkdir $DIR/$tdir
24745
24746         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24747                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24748         stat $DIR/$tdir
24749
24750 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24751         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24752         local facet=mds$((mdtidx + 1))
24753         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24754         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24755
24756         stop $facet || error "stop MDS failed"
24757         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24758                 error "start MDS fail"
24759         wait_recovery_complete $facet
24760 }
24761 run_test 257 "xattr locks are not lost"
24762
24763 # Verify we take the i_mutex when security requires it
24764 test_258a() {
24765 #define OBD_FAIL_IMUTEX_SEC 0x141c
24766         $LCTL set_param fail_loc=0x141c
24767         touch $DIR/$tfile
24768         chmod u+s $DIR/$tfile
24769         chmod a+rwx $DIR/$tfile
24770         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24771         RC=$?
24772         if [ $RC -ne 0 ]; then
24773                 error "error, failed to take i_mutex, rc=$?"
24774         fi
24775         rm -f $DIR/$tfile
24776 }
24777 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24778
24779 # Verify we do NOT take the i_mutex in the normal case
24780 test_258b() {
24781 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24782         $LCTL set_param fail_loc=0x141d
24783         touch $DIR/$tfile
24784         chmod a+rwx $DIR
24785         chmod a+rw $DIR/$tfile
24786         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24787         RC=$?
24788         if [ $RC -ne 0 ]; then
24789                 error "error, took i_mutex unnecessarily, rc=$?"
24790         fi
24791         rm -f $DIR/$tfile
24792
24793 }
24794 run_test 258b "verify i_mutex security behavior"
24795
24796 test_259() {
24797         local file=$DIR/$tfile
24798         local before
24799         local after
24800
24801         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24802
24803         stack_trap "rm -f $file" EXIT
24804
24805         wait_delete_completed
24806         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24807         echo "before: $before"
24808
24809         $LFS setstripe -i 0 -c 1 $file
24810         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24811         sync_all_data
24812         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24813         echo "after write: $after"
24814
24815 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24816         do_facet ost1 $LCTL set_param fail_loc=0x2301
24817         $TRUNCATE $file 0
24818         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24819         echo "after truncate: $after"
24820
24821         stop ost1
24822         do_facet ost1 $LCTL set_param fail_loc=0
24823         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24824         sleep 2
24825         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24826         echo "after restart: $after"
24827         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24828                 error "missing truncate?"
24829
24830         return 0
24831 }
24832 run_test 259 "crash at delayed truncate"
24833
24834 test_260() {
24835 #define OBD_FAIL_MDC_CLOSE               0x806
24836         $LCTL set_param fail_loc=0x80000806
24837         touch $DIR/$tfile
24838
24839 }
24840 run_test 260 "Check mdc_close fail"
24841
24842 ### Data-on-MDT sanity tests ###
24843 test_270a() {
24844         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24845                 skip "Need MDS version at least 2.10.55 for DoM"
24846
24847         # create DoM file
24848         local dom=$DIR/$tdir/dom_file
24849         local tmp=$DIR/$tdir/tmp_file
24850
24851         mkdir_on_mdt0 $DIR/$tdir
24852
24853         # basic checks for DoM component creation
24854         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24855                 error "Can set MDT layout to non-first entry"
24856
24857         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24858                 error "Can define multiple entries as MDT layout"
24859
24860         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24861
24862         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24863         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24864         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24865
24866         local mdtidx=$($LFS getstripe -m $dom)
24867         local mdtname=MDT$(printf %04x $mdtidx)
24868         local facet=mds$((mdtidx + 1))
24869         local space_check=1
24870
24871         # Skip free space checks with ZFS
24872         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24873
24874         # write
24875         sync
24876         local size_tmp=$((65536 * 3))
24877         local mdtfree1=$(do_facet $facet \
24878                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24879
24880         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24881         # check also direct IO along write
24882         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24883         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24884         sync
24885         cmp $tmp $dom || error "file data is different"
24886         [ $(stat -c%s $dom) == $size_tmp ] ||
24887                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24888         if [ $space_check == 1 ]; then
24889                 local mdtfree2=$(do_facet $facet \
24890                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24891
24892                 # increase in usage from by $size_tmp
24893                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24894                         error "MDT free space wrong after write: " \
24895                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24896         fi
24897
24898         # truncate
24899         local size_dom=10000
24900
24901         $TRUNCATE $dom $size_dom
24902         [ $(stat -c%s $dom) == $size_dom ] ||
24903                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24904         if [ $space_check == 1 ]; then
24905                 mdtfree1=$(do_facet $facet \
24906                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24907                 # decrease in usage from $size_tmp to new $size_dom
24908                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24909                   $(((size_tmp - size_dom) / 1024)) ] ||
24910                         error "MDT free space is wrong after truncate: " \
24911                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24912         fi
24913
24914         # append
24915         cat $tmp >> $dom
24916         sync
24917         size_dom=$((size_dom + size_tmp))
24918         [ $(stat -c%s $dom) == $size_dom ] ||
24919                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24920         if [ $space_check == 1 ]; then
24921                 mdtfree2=$(do_facet $facet \
24922                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24923                 # increase in usage by $size_tmp from previous
24924                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24925                         error "MDT free space is wrong after append: " \
24926                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24927         fi
24928
24929         # delete
24930         rm $dom
24931         if [ $space_check == 1 ]; then
24932                 mdtfree1=$(do_facet $facet \
24933                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24934                 # decrease in usage by $size_dom from previous
24935                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24936                         error "MDT free space is wrong after removal: " \
24937                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24938         fi
24939
24940         # combined striping
24941         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24942                 error "Can't create DoM + OST striping"
24943
24944         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24945         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24946         # check also direct IO along write
24947         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24948         sync
24949         cmp $tmp $dom || error "file data is different"
24950         [ $(stat -c%s $dom) == $size_tmp ] ||
24951                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24952         rm $dom $tmp
24953
24954         return 0
24955 }
24956 run_test 270a "DoM: basic functionality tests"
24957
24958 test_270b() {
24959         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24960                 skip "Need MDS version at least 2.10.55"
24961
24962         local dom=$DIR/$tdir/dom_file
24963         local max_size=1048576
24964
24965         mkdir -p $DIR/$tdir
24966         $LFS setstripe -E $max_size -L mdt $dom
24967
24968         # truncate over the limit
24969         $TRUNCATE $dom $(($max_size + 1)) &&
24970                 error "successful truncate over the maximum size"
24971         # write over the limit
24972         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24973                 error "successful write over the maximum size"
24974         # append over the limit
24975         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24976         echo "12345" >> $dom && error "successful append over the maximum size"
24977         rm $dom
24978
24979         return 0
24980 }
24981 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24982
24983 test_270c() {
24984         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24985                 skip "Need MDS version at least 2.10.55"
24986
24987         mkdir -p $DIR/$tdir
24988         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24989
24990         # check files inherit DoM EA
24991         touch $DIR/$tdir/first
24992         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24993                 error "bad pattern"
24994         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24995                 error "bad stripe count"
24996         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24997                 error "bad stripe size"
24998
24999         # check directory inherits DoM EA and uses it as default
25000         mkdir $DIR/$tdir/subdir
25001         touch $DIR/$tdir/subdir/second
25002         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
25003                 error "bad pattern in sub-directory"
25004         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
25005                 error "bad stripe count in sub-directory"
25006         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
25007                 error "bad stripe size in sub-directory"
25008         return 0
25009 }
25010 run_test 270c "DoM: DoM EA inheritance tests"
25011
25012 test_270d() {
25013         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25014                 skip "Need MDS version at least 2.10.55"
25015
25016         mkdir -p $DIR/$tdir
25017         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25018
25019         # inherit default DoM striping
25020         mkdir $DIR/$tdir/subdir
25021         touch $DIR/$tdir/subdir/f1
25022
25023         # change default directory striping
25024         $LFS setstripe -c 1 $DIR/$tdir/subdir
25025         touch $DIR/$tdir/subdir/f2
25026         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
25027                 error "wrong default striping in file 2"
25028         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
25029                 error "bad pattern in file 2"
25030         return 0
25031 }
25032 run_test 270d "DoM: change striping from DoM to RAID0"
25033
25034 test_270e() {
25035         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25036                 skip "Need MDS version at least 2.10.55"
25037
25038         mkdir -p $DIR/$tdir/dom
25039         mkdir -p $DIR/$tdir/norm
25040         DOMFILES=20
25041         NORMFILES=10
25042         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
25043         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
25044
25045         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
25046         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
25047
25048         # find DoM files by layout
25049         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
25050         [ $NUM -eq  $DOMFILES ] ||
25051                 error "lfs find -L: found $NUM, expected $DOMFILES"
25052         echo "Test 1: lfs find 20 DOM files by layout: OK"
25053
25054         # there should be 1 dir with default DOM striping
25055         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
25056         [ $NUM -eq  1 ] ||
25057                 error "lfs find -L: found $NUM, expected 1 dir"
25058         echo "Test 2: lfs find 1 DOM dir by layout: OK"
25059
25060         # find DoM files by stripe size
25061         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
25062         [ $NUM -eq  $DOMFILES ] ||
25063                 error "lfs find -S: found $NUM, expected $DOMFILES"
25064         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
25065
25066         # find files by stripe offset except DoM files
25067         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
25068         [ $NUM -eq  $NORMFILES ] ||
25069                 error "lfs find -i: found $NUM, expected $NORMFILES"
25070         echo "Test 5: lfs find no DOM files by stripe index: OK"
25071         return 0
25072 }
25073 run_test 270e "DoM: lfs find with DoM files test"
25074
25075 test_270f() {
25076         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25077                 skip "Need MDS version at least 2.10.55"
25078
25079         local mdtname=${FSNAME}-MDT0000-mdtlov
25080         local dom=$DIR/$tdir/dom_file
25081         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
25082                                                 lod.$mdtname.dom_stripesize)
25083         local dom_limit=131072
25084
25085         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
25086         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25087                                                 lod.$mdtname.dom_stripesize)
25088         [ ${dom_limit} -eq ${dom_current} ] ||
25089                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
25090
25091         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25092         $LFS setstripe -d $DIR/$tdir
25093         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
25094                 error "Can't set directory default striping"
25095
25096         # exceed maximum stripe size
25097         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25098                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
25099         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
25100                 error "Able to create DoM component size more than LOD limit"
25101
25102         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25103         dom_current=$(do_facet mds1 $LCTL get_param -n \
25104                                                 lod.$mdtname.dom_stripesize)
25105         [ 0 -eq ${dom_current} ] ||
25106                 error "Can't set zero DoM stripe limit"
25107         rm $dom
25108
25109         # attempt to create DoM file on server with disabled DoM should
25110         # remove DoM entry from layout and be succeed
25111         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
25112                 error "Can't create DoM file (DoM is disabled)"
25113         [ $($LFS getstripe -L $dom) == "mdt" ] &&
25114                 error "File has DoM component while DoM is disabled"
25115         rm $dom
25116
25117         # attempt to create DoM file with only DoM stripe should return error
25118         $LFS setstripe -E $dom_limit -L mdt $dom &&
25119                 error "Able to create DoM-only file while DoM is disabled"
25120
25121         # too low values to be aligned with smallest stripe size 64K
25122         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
25123         dom_current=$(do_facet mds1 $LCTL get_param -n \
25124                                                 lod.$mdtname.dom_stripesize)
25125         [ 30000 -eq ${dom_current} ] &&
25126                 error "Can set too small DoM stripe limit"
25127
25128         # 64K is a minimal stripe size in Lustre, expect limit of that size
25129         [ 65536 -eq ${dom_current} ] ||
25130                 error "Limit is not set to 64K but ${dom_current}"
25131
25132         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
25133         dom_current=$(do_facet mds1 $LCTL get_param -n \
25134                                                 lod.$mdtname.dom_stripesize)
25135         echo $dom_current
25136         [ 2147483648 -eq ${dom_current} ] &&
25137                 error "Can set too large DoM stripe limit"
25138
25139         do_facet mds1 $LCTL set_param -n \
25140                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
25141         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25142                 error "Can't create DoM component size after limit change"
25143         do_facet mds1 $LCTL set_param -n \
25144                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
25145         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25146                 error "Can't create DoM file after limit decrease"
25147         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25148                 error "Can create big DoM component after limit decrease"
25149         touch ${dom}_def ||
25150                 error "Can't create file with old default layout"
25151
25152         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25153         return 0
25154 }
25155 run_test 270f "DoM: maximum DoM stripe size checks"
25156
25157 test_270g() {
25158         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25159                 skip "Need MDS version at least 2.13.52"
25160         local dom=$DIR/$tdir/$tfile
25161
25162         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25163         local lodname=${FSNAME}-MDT0000-mdtlov
25164
25165         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25166         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25167         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25168         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25169
25170         local dom_limit=1024
25171         local dom_threshold="50%"
25172
25173         $LFS setstripe -d $DIR/$tdir
25174         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25175                 error "Can't set directory default striping"
25176
25177         do_facet mds1 $LCTL set_param -n \
25178                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25179         # set 0 threshold and create DOM file to change tunable stripesize
25180         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25181         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25182                 error "Failed to create $dom file"
25183         # now tunable dom_cur_stripesize should reach maximum
25184         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25185                                         lod.${lodname}.dom_stripesize_cur_kb)
25186         [[ $dom_current == $dom_limit ]] ||
25187                 error "Current DOM stripesize is not maximum"
25188         rm $dom
25189
25190         # set threshold for further tests
25191         do_facet mds1 $LCTL set_param -n \
25192                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25193         echo "DOM threshold is $dom_threshold free space"
25194         local dom_def
25195         local dom_set
25196         # Spoof bfree to exceed threshold
25197         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25198         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25199         for spfree in 40 20 0 15 30 55; do
25200                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25201                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25202                         error "Failed to create $dom file"
25203                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25204                                         lod.${lodname}.dom_stripesize_cur_kb)
25205                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25206                 [[ $dom_def != $dom_current ]] ||
25207                         error "Default stripe size was not changed"
25208                 if (( spfree > 0 )) ; then
25209                         dom_set=$($LFS getstripe -S $dom)
25210                         (( dom_set == dom_def * 1024 )) ||
25211                                 error "DOM component size is still old"
25212                 else
25213                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25214                                 error "DoM component is set with no free space"
25215                 fi
25216                 rm $dom
25217                 dom_current=$dom_def
25218         done
25219 }
25220 run_test 270g "DoM: default DoM stripe size depends on free space"
25221
25222 test_270h() {
25223         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25224                 skip "Need MDS version at least 2.13.53"
25225
25226         local mdtname=${FSNAME}-MDT0000-mdtlov
25227         local dom=$DIR/$tdir/$tfile
25228         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25229
25230         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25231         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25232
25233         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25234         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25235                 error "can't create OST file"
25236         # mirrored file with DOM entry in the second mirror
25237         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25238                 error "can't create mirror with DoM component"
25239
25240         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25241
25242         # DOM component in the middle and has other enries in the same mirror,
25243         # should succeed but lost DoM component
25244         $LFS setstripe --copy=${dom}_1 $dom ||
25245                 error "Can't create file from OST|DOM mirror layout"
25246         # check new file has no DoM layout after all
25247         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25248                 error "File has DoM component while DoM is disabled"
25249 }
25250 run_test 270h "DoM: DoM stripe removal when disabled on server"
25251
25252 test_270i() {
25253         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25254                 skip "Need MDS version at least 2.14.54"
25255
25256         mkdir $DIR/$tdir
25257         # DoM with plain layout
25258         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25259                 error "default plain layout with DoM must fail"
25260         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25261                 error "setstripe plain file layout with DoM must fail"
25262         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25263                 error "default DoM layout with bad striping must fail"
25264         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25265                 error "setstripe to DoM layout with bad striping must fail"
25266         return 0
25267 }
25268 run_test 270i "DoM: setting invalid DoM striping should fail"
25269
25270 test_270j() {
25271         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25272                 skip "Need MDS version at least 2.15.55.203"
25273
25274         local dom=$DIR/$tdir/$tfile
25275         local odv
25276         local ndv
25277
25278         mkdir -p $DIR/$tdir
25279
25280         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25281
25282         odv=$($LFS data_version $dom)
25283         chmod 666 $dom
25284         mv $dom ${dom}_moved
25285         link ${dom}_moved $dom
25286         setfattr -n user.attrx -v "some_attr" $dom
25287         ndv=$($LFS data_version $dom)
25288         (( $ndv == $odv )) ||
25289                 error "data version was changed by metadata operations"
25290
25291         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25292                 error "failed to write data into $dom"
25293         cancel_lru_locks mdc
25294         ndv=$($LFS data_version $dom)
25295         (( $ndv != $odv )) ||
25296                 error "data version wasn't changed on write"
25297
25298         odv=$ndv
25299         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25300         ndv=$($LFS data_version $dom)
25301         (( $ndv != $odv )) ||
25302                 error "data version wasn't changed on truncate down"
25303
25304         odv=$ndv
25305         $TRUNCATE $dom 25000
25306         ndv=$($LFS data_version $dom)
25307         (( $ndv != $odv )) ||
25308                 error "data version wasn't changed on truncate up"
25309
25310         # check also fallocate for ldiskfs
25311         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25312                 odv=$ndv
25313                 fallocate -l 1048576 $dom
25314                 ndv=$($LFS data_version $dom)
25315                 (( $ndv != $odv )) ||
25316                         error "data version wasn't changed on fallocate"
25317
25318                 odv=$ndv
25319                 fallocate -p --offset 4096 -l 4096 $dom
25320                 ndv=$($LFS data_version $dom)
25321                 (( $ndv != $odv )) ||
25322                         error "data version wasn't changed on fallocate punch"
25323         fi
25324 }
25325 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25326
25327 test_271a() {
25328         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25329                 skip "Need MDS version at least 2.10.55"
25330
25331         local dom=$DIR/$tdir/dom
25332
25333         mkdir -p $DIR/$tdir
25334
25335         $LFS setstripe -E 1024K -L mdt $dom
25336
25337         lctl set_param -n mdc.*.stats=clear
25338         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25339         cat $dom > /dev/null
25340         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25341         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25342         ls $dom
25343         rm -f $dom
25344 }
25345 run_test 271a "DoM: data is cached for read after write"
25346
25347 test_271b() {
25348         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25349                 skip "Need MDS version at least 2.10.55"
25350
25351         local dom=$DIR/$tdir/dom
25352
25353         mkdir -p $DIR/$tdir
25354
25355         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25356
25357         lctl set_param -n mdc.*.stats=clear
25358         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25359         cancel_lru_locks mdc
25360         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25361         # second stat to check size is cached on client
25362         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25363         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25364         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25365         rm -f $dom
25366 }
25367 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25368
25369 test_271ba() {
25370         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25371                 skip "Need MDS version at least 2.10.55"
25372
25373         local dom=$DIR/$tdir/dom
25374
25375         mkdir -p $DIR/$tdir
25376
25377         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25378
25379         lctl set_param -n mdc.*.stats=clear
25380         lctl set_param -n osc.*.stats=clear
25381         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25382         cancel_lru_locks mdc
25383         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25384         # second stat to check size is cached on client
25385         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25386         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25387         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25388         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25389         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25390         rm -f $dom
25391 }
25392 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25393
25394
25395 get_mdc_stats() {
25396         local mdtidx=$1
25397         local param=$2
25398         local mdt=MDT$(printf %04x $mdtidx)
25399
25400         if [ -z $param ]; then
25401                 lctl get_param -n mdc.*$mdt*.stats
25402         else
25403                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25404         fi
25405 }
25406
25407 test_271c() {
25408         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25409                 skip "Need MDS version at least 2.10.55"
25410
25411         local dom=$DIR/$tdir/dom
25412
25413         mkdir -p $DIR/$tdir
25414
25415         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25416
25417         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25418         local facet=mds$((mdtidx + 1))
25419
25420         cancel_lru_locks mdc
25421         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25422         createmany -o $dom 1000
25423         lctl set_param -n mdc.*.stats=clear
25424         smalliomany -w $dom 1000 200
25425         get_mdc_stats $mdtidx
25426         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25427         # Each file has 1 open, 1 IO enqueues, total 2000
25428         # but now we have also +1 getxattr for security.capability, total 3000
25429         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25430         unlinkmany $dom 1000
25431
25432         cancel_lru_locks mdc
25433         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25434         createmany -o $dom 1000
25435         lctl set_param -n mdc.*.stats=clear
25436         smalliomany -w $dom 1000 200
25437         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25438         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25439         # for OPEN and IO lock.
25440         [ $((enq - enq_2)) -ge 1000 ] ||
25441                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25442         unlinkmany $dom 1000
25443         return 0
25444 }
25445 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25446
25447 cleanup_271def_tests() {
25448         trap 0
25449         rm -f $1
25450 }
25451
25452 test_271d() {
25453         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25454                 skip "Need MDS version at least 2.10.57"
25455
25456         local dom=$DIR/$tdir/dom
25457         local tmp=$TMP/$tfile
25458         trap "cleanup_271def_tests $tmp" EXIT
25459
25460         mkdir -p $DIR/$tdir
25461
25462         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25463
25464         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25465
25466         cancel_lru_locks mdc
25467         dd if=/dev/urandom of=$tmp bs=1000 count=1
25468         dd if=$tmp of=$dom bs=1000 count=1
25469         cancel_lru_locks mdc
25470
25471         cat /etc/hosts >> $tmp
25472         lctl set_param -n mdc.*.stats=clear
25473
25474         # append data to the same file it should update local page
25475         echo "Append to the same page"
25476         cat /etc/hosts >> $dom
25477         local num=$(get_mdc_stats $mdtidx ost_read)
25478         local ra=$(get_mdc_stats $mdtidx req_active)
25479         local rw=$(get_mdc_stats $mdtidx req_waittime)
25480
25481         [ -z $num ] || error "$num READ RPC occured"
25482         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25483         echo "... DONE"
25484
25485         # compare content
25486         cmp $tmp $dom || error "file miscompare"
25487
25488         cancel_lru_locks mdc
25489         lctl set_param -n mdc.*.stats=clear
25490
25491         echo "Open and read file"
25492         cat $dom > /dev/null
25493         local num=$(get_mdc_stats $mdtidx ost_read)
25494         local ra=$(get_mdc_stats $mdtidx req_active)
25495         local rw=$(get_mdc_stats $mdtidx req_waittime)
25496
25497         [ -z $num ] || error "$num READ RPC occured"
25498         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25499         echo "... DONE"
25500
25501         # compare content
25502         cmp $tmp $dom || error "file miscompare"
25503
25504         return 0
25505 }
25506 run_test 271d "DoM: read on open (1K file in reply buffer)"
25507
25508 test_271f() {
25509         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25510                 skip "Need MDS version at least 2.10.57"
25511
25512         local dom=$DIR/$tdir/dom
25513         local tmp=$TMP/$tfile
25514         trap "cleanup_271def_tests $tmp" EXIT
25515
25516         mkdir -p $DIR/$tdir
25517
25518         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25519
25520         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25521
25522         cancel_lru_locks mdc
25523         dd if=/dev/urandom of=$tmp bs=265000 count=1
25524         dd if=$tmp of=$dom bs=265000 count=1
25525         cancel_lru_locks mdc
25526         cat /etc/hosts >> $tmp
25527         lctl set_param -n mdc.*.stats=clear
25528
25529         echo "Append to the same page"
25530         cat /etc/hosts >> $dom
25531         local num=$(get_mdc_stats $mdtidx ost_read)
25532         local ra=$(get_mdc_stats $mdtidx req_active)
25533         local rw=$(get_mdc_stats $mdtidx req_waittime)
25534
25535         [ -z $num ] || error "$num READ RPC occured"
25536         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25537         echo "... DONE"
25538
25539         # compare content
25540         cmp $tmp $dom || error "file miscompare"
25541
25542         cancel_lru_locks mdc
25543         lctl set_param -n mdc.*.stats=clear
25544
25545         echo "Open and read file"
25546         cat $dom > /dev/null
25547         local num=$(get_mdc_stats $mdtidx ost_read)
25548         local ra=$(get_mdc_stats $mdtidx req_active)
25549         local rw=$(get_mdc_stats $mdtidx req_waittime)
25550
25551         [ -z $num ] && num=0
25552         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25553         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25554         echo "... DONE"
25555
25556         # compare content
25557         cmp $tmp $dom || error "file miscompare"
25558
25559         return 0
25560 }
25561 run_test 271f "DoM: read on open (200K file and read tail)"
25562
25563 test_271g() {
25564         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25565                 skip "Skipping due to old client or server version"
25566
25567         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25568         # to get layout
25569         $CHECKSTAT -t file $DIR1/$tfile
25570
25571         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25572         MULTIOP_PID=$!
25573         sleep 1
25574         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25575         $LCTL set_param fail_loc=0x80000314
25576         rm $DIR1/$tfile || error "Unlink fails"
25577         RC=$?
25578         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25579         [ $RC -eq 0 ] || error "Failed write to stale object"
25580 }
25581 run_test 271g "Discard DoM data vs client flush race"
25582
25583 test_272a() {
25584         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25585                 skip "Need MDS version at least 2.11.50"
25586
25587         local dom=$DIR/$tdir/dom
25588         mkdir -p $DIR/$tdir
25589
25590         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25591         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25592                 error "failed to write data into $dom"
25593         local old_md5=$(md5sum $dom)
25594
25595         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25596                 error "failed to migrate to the same DoM component"
25597
25598         local new_md5=$(md5sum $dom)
25599
25600         [ "$old_md5" == "$new_md5" ] ||
25601                 error "md5sum differ: $old_md5, $new_md5"
25602
25603         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25604                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25605 }
25606 run_test 272a "DoM migration: new layout with the same DOM component"
25607
25608 test_272b() {
25609         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25610                 skip "Need MDS version at least 2.11.50"
25611
25612         local dom=$DIR/$tdir/dom
25613         mkdir -p $DIR/$tdir
25614         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25615         stack_trap "rm -rf $DIR/$tdir"
25616
25617         local mdtidx=$($LFS getstripe -m $dom)
25618         local mdtname=MDT$(printf %04x $mdtidx)
25619         local facet=mds$((mdtidx + 1))
25620
25621         local mdtfree1=$(do_facet $facet \
25622                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25623         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25624                 error "failed to write data into $dom"
25625         local old_md5=$(md5sum $dom)
25626         cancel_lru_locks mdc
25627         local mdtfree1=$(do_facet $facet \
25628                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25629
25630         $LFS migrate -c2 $dom ||
25631                 error "failed to migrate to the new composite layout"
25632         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25633                 error "MDT stripe was not removed"
25634         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25635                 error "$dir1 shouldn't have DATAVER EA"
25636
25637         cancel_lru_locks mdc
25638         local new_md5=$(md5sum $dom)
25639         [ "$old_md5" == "$new_md5" ] ||
25640                 error "$old_md5 != $new_md5"
25641
25642         # Skip free space checks with ZFS
25643         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25644                 local mdtfree2=$(do_facet $facet \
25645                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25646                 [ $mdtfree2 -gt $mdtfree1 ] ||
25647                         error "MDT space is not freed after migration"
25648         fi
25649         return 0
25650 }
25651 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25652
25653 test_272c() {
25654         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25655                 skip "Need MDS version at least 2.11.50"
25656
25657         local dom=$DIR/$tdir/$tfile
25658         mkdir -p $DIR/$tdir
25659         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25660         stack_trap "rm -rf $DIR/$tdir"
25661
25662         local mdtidx=$($LFS getstripe -m $dom)
25663         local mdtname=MDT$(printf %04x $mdtidx)
25664         local facet=mds$((mdtidx + 1))
25665
25666         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25667                 error "failed to write data into $dom"
25668         local old_md5=$(md5sum $dom)
25669         cancel_lru_locks mdc
25670         local mdtfree1=$(do_facet $facet \
25671                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25672
25673         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25674                 error "failed to migrate to the new composite layout"
25675         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25676                 error "MDT stripe was not removed"
25677
25678         cancel_lru_locks mdc
25679         local new_md5=$(md5sum $dom)
25680         [ "$old_md5" == "$new_md5" ] ||
25681                 error "$old_md5 != $new_md5"
25682
25683         # Skip free space checks with ZFS
25684         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25685                 local mdtfree2=$(do_facet $facet \
25686                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25687                 [ $mdtfree2 -gt $mdtfree1 ] ||
25688                         error "MDS space is not freed after migration"
25689         fi
25690         return 0
25691 }
25692 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25693
25694 test_272d() {
25695         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25696                 skip "Need MDS version at least 2.12.55"
25697
25698         local dom=$DIR/$tdir/$tfile
25699         mkdir -p $DIR/$tdir
25700         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25701
25702         local mdtidx=$($LFS getstripe -m $dom)
25703         local mdtname=MDT$(printf %04x $mdtidx)
25704         local facet=mds$((mdtidx + 1))
25705
25706         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25707                 error "failed to write data into $dom"
25708         local old_md5=$(md5sum $dom)
25709         cancel_lru_locks mdc
25710         local mdtfree1=$(do_facet $facet \
25711                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25712
25713         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25714                 error "failed mirroring to the new composite layout"
25715         $LFS mirror resync $dom ||
25716                 error "failed mirror resync"
25717         $LFS mirror split --mirror-id 1 -d $dom ||
25718                 error "failed mirror split"
25719
25720         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25721                 error "MDT stripe was not removed"
25722
25723         cancel_lru_locks mdc
25724         local new_md5=$(md5sum $dom)
25725         [ "$old_md5" == "$new_md5" ] ||
25726                 error "$old_md5 != $new_md5"
25727
25728         # Skip free space checks with ZFS
25729         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25730                 local mdtfree2=$(do_facet $facet \
25731                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25732                 [ $mdtfree2 -gt $mdtfree1 ] ||
25733                         error "MDS space is not freed after DOM mirror deletion"
25734         fi
25735         return 0
25736 }
25737 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25738
25739 test_272e() {
25740         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25741                 skip "Need MDS version at least 2.12.55"
25742
25743         local dom=$DIR/$tdir/$tfile
25744         mkdir -p $DIR/$tdir
25745         $LFS setstripe -c 2 $dom
25746
25747         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25748                 error "failed to write data into $dom"
25749         local old_md5=$(md5sum $dom)
25750         cancel_lru_locks
25751
25752         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25753                 error "failed mirroring to the DOM layout"
25754         $LFS mirror resync $dom ||
25755                 error "failed mirror resync"
25756         $LFS mirror split --mirror-id 1 -d $dom ||
25757                 error "failed mirror split"
25758
25759         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25760                 error "MDT stripe wasn't set"
25761
25762         cancel_lru_locks
25763         local new_md5=$(md5sum $dom)
25764         [ "$old_md5" == "$new_md5" ] ||
25765                 error "$old_md5 != $new_md5"
25766
25767         return 0
25768 }
25769 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25770
25771 test_272f() {
25772         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25773                 skip "Need MDS version at least 2.12.55"
25774
25775         local dom=$DIR/$tdir/$tfile
25776         mkdir -p $DIR/$tdir
25777         $LFS setstripe -c 2 $dom
25778
25779         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25780                 error "failed to write data into $dom"
25781         local old_md5=$(md5sum $dom)
25782         cancel_lru_locks
25783
25784         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25785                 error "failed migrating to the DOM file"
25786
25787         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25788                 error "MDT stripe wasn't set"
25789
25790         cancel_lru_locks
25791         local new_md5=$(md5sum $dom)
25792         [ "$old_md5" != "$new_md5" ] &&
25793                 error "$old_md5 != $new_md5"
25794
25795         return 0
25796 }
25797 run_test 272f "DoM migration: OST-striped file to DOM file"
25798
25799 test_273a() {
25800         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25801                 skip "Need MDS version at least 2.11.50"
25802
25803         # Layout swap cannot be done if either file has DOM component,
25804         # this will never be supported, migration should be used instead
25805
25806         local dom=$DIR/$tdir/$tfile
25807         mkdir -p $DIR/$tdir
25808
25809         $LFS setstripe -c2 ${dom}_plain
25810         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25811         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25812                 error "can swap layout with DoM component"
25813         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25814                 error "can swap layout with DoM component"
25815
25816         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25817         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25818                 error "can swap layout with DoM component"
25819         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25820                 error "can swap layout with DoM component"
25821         return 0
25822 }
25823 run_test 273a "DoM: layout swapping should fail with DOM"
25824
25825 test_273b() {
25826         mkdir -p $DIR/$tdir
25827         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25828
25829 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25830         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25831
25832         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25833 }
25834 run_test 273b "DoM: race writeback and object destroy"
25835
25836 test_273c() {
25837         mkdir -p $DIR/$tdir
25838         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25839
25840         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25841         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25842
25843         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25844 }
25845 run_test 273c "race writeback and object destroy"
25846
25847 test_275() {
25848         remote_ost_nodsh && skip "remote OST with nodsh"
25849         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25850                 skip "Need OST version >= 2.10.57"
25851
25852         local file=$DIR/$tfile
25853         local oss
25854
25855         oss=$(comma_list $(osts_nodes))
25856
25857         dd if=/dev/urandom of=$file bs=1M count=2 ||
25858                 error "failed to create a file"
25859         stack_trap "rm -f $file"
25860         cancel_lru_locks osc
25861
25862         #lock 1
25863         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25864                 error "failed to read a file"
25865
25866 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25867         $LCTL set_param fail_loc=0x8000031f
25868
25869         cancel_lru_locks osc &
25870         sleep 1
25871
25872 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25873         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25874         #IO takes another lock, but matches the PENDING one
25875         #and places it to the IO RPC
25876         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25877                 error "failed to read a file with PENDING lock"
25878 }
25879 run_test 275 "Read on a canceled duplicate lock"
25880
25881 test_276() {
25882         remote_ost_nodsh && skip "remote OST with nodsh"
25883         local pid
25884
25885         do_facet ost1 "(while true; do \
25886                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25887                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25888         pid=$!
25889
25890         for LOOP in $(seq 20); do
25891                 stop ost1
25892                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25893         done
25894         kill -9 $pid
25895         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25896                 rm $TMP/sanity_276_pid"
25897 }
25898 run_test 276 "Race between mount and obd_statfs"
25899
25900 test_277() {
25901         $LCTL set_param ldlm.namespaces.*.lru_size=0
25902         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25903         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25904                           awk '/^used_mb/ { print $2 }')
25905         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25906         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25907                 oflag=direct conv=notrunc
25908         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25909                     awk '/^used_mb/ { print $2 }')
25910         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25911 }
25912 run_test 277 "Direct IO shall drop page cache"
25913
25914 test_278() {
25915         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25916         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25917         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25918                 skip "needs the same host for mdt1 mdt2" && return
25919
25920         local pid1
25921         local pid2
25922
25923 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25924         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25925         stop mds2 &
25926         pid2=$!
25927
25928         stop mds1
25929
25930         echo "Starting MDTs"
25931         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25932         wait $pid2
25933 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25934 #will return NULL
25935         do_facet mds2 $LCTL set_param fail_loc=0
25936
25937         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25938         wait_recovery_complete mds2
25939 }
25940 run_test 278 "Race starting MDS between MDTs stop/start"
25941
25942 test_280() {
25943         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25944                 skip "Need MGS version at least 2.13.52"
25945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25946         combined_mgs_mds || skip "needs combined MGS/MDT"
25947
25948         umount_client $MOUNT
25949 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25950         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25951
25952         mount_client $MOUNT &
25953         sleep 1
25954         stop mgs || error "stop mgs failed"
25955         #for a race mgs would crash
25956         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25957         # make sure we unmount client before remounting
25958         wait
25959         umount_client $MOUNT
25960         mount_client $MOUNT || error "mount client failed"
25961 }
25962 run_test 280 "Race between MGS umount and client llog processing"
25963
25964 cleanup_test_300() {
25965         trap 0
25966         umask $SAVE_UMASK
25967 }
25968
25969 test_striped_dir() {
25970         local mdt_index=$1
25971         local stripe_count=$2
25972         local overstriping=$3
25973         local stripe_index
25974         local getstripe_count
25975
25976         mkdir -p $DIR/$tdir
25977
25978         SAVE_UMASK=$(umask)
25979         trap cleanup_test_300 RETURN EXIT
25980
25981         if [ -z $overstriping ]; then
25982                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25983                                         -o 755 $DIR/$tdir/striped_dir ||
25984                         error "set striped dir error"
25985         else
25986                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25987                                         -o 755 $DIR/$tdir/striped_dir ||
25988                         error "set striped dir error"
25989         fi
25990
25991         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25992         [ "$mode" = "755" ] || error "expect 755 got $mode"
25993
25994         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25995                 error "getdirstripe failed"
25996         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25997         if [ "$getstripe_count" != "$stripe_count" ]; then
25998                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25999         fi
26000         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
26001         if [ "$getstripe_count" != "$stripe_count" ]; then
26002                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
26003         fi
26004
26005         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
26006         if [ "$stripe_index" != "$mdt_index" ]; then
26007                 error "stripe_index is $stripe_index, expect $mdt_index"
26008         fi
26009
26010         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
26011                 error "nlink error after create striped dir"
26012
26013         mkdir $DIR/$tdir/striped_dir/a
26014         mkdir $DIR/$tdir/striped_dir/b
26015
26016         stat $DIR/$tdir/striped_dir/a ||
26017                 error "create dir under striped dir failed"
26018         stat $DIR/$tdir/striped_dir/b ||
26019                 error "create dir under striped dir failed"
26020
26021         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
26022                 error "nlink error after mkdir"
26023
26024         rmdir $DIR/$tdir/striped_dir/a
26025         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
26026                 error "nlink error after rmdir"
26027
26028         rmdir $DIR/$tdir/striped_dir/b
26029         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
26030                 error "nlink error after rmdir"
26031
26032         chattr +i $DIR/$tdir/striped_dir
26033         createmany -o $DIR/$tdir/striped_dir/f 10 &&
26034                 error "immutable flags not working under striped dir!"
26035         chattr -i $DIR/$tdir/striped_dir
26036
26037         rmdir $DIR/$tdir/striped_dir ||
26038                 error "rmdir striped dir error"
26039
26040         cleanup_test_300
26041
26042         true
26043 }
26044
26045 test_300a() {
26046         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26047                 skip "skipped for lustre < 2.7.0"
26048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26050
26051         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
26052         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
26053 }
26054 run_test 300a "basic striped dir sanity test"
26055
26056 test_300b() {
26057         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26058                 skip "skipped for lustre < 2.7.0"
26059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26061
26062         local i
26063         local mtime1
26064         local mtime2
26065         local mtime3
26066
26067         test_mkdir $DIR/$tdir || error "mkdir fail"
26068         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26069                 error "set striped dir error"
26070         for i in {0..9}; do
26071                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
26072                 sleep 1
26073                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
26074                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
26075                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
26076                 sleep 1
26077                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
26078                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
26079                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
26080         done
26081         true
26082 }
26083 run_test 300b "check ctime/mtime for striped dir"
26084
26085 test_300c() {
26086         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26087                 skip "skipped for lustre < 2.7.0"
26088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26089         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26090
26091         local file_count
26092
26093         mkdir_on_mdt0 $DIR/$tdir
26094         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
26095                 error "set striped dir error"
26096
26097         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
26098                 error "chown striped dir failed"
26099
26100         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
26101                 error "create 5k files failed"
26102
26103         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
26104
26105         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
26106
26107         rm -rf $DIR/$tdir
26108 }
26109 run_test 300c "chown && check ls under striped directory"
26110
26111 test_300d() {
26112         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26113                 skip "skipped for lustre < 2.7.0"
26114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26115         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26116
26117         local stripe_count
26118         local file
26119
26120         mkdir -p $DIR/$tdir
26121         $LFS setstripe -c 2 $DIR/$tdir
26122
26123         #local striped directory
26124         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26125                 error "set striped dir error"
26126         #look at the directories for debug purposes
26127         ls -l $DIR/$tdir
26128         $LFS getdirstripe $DIR/$tdir
26129         ls -l $DIR/$tdir/striped_dir
26130         $LFS getdirstripe $DIR/$tdir/striped_dir
26131         createmany -o $DIR/$tdir/striped_dir/f 10 ||
26132                 error "create 10 files failed"
26133
26134         #remote striped directory
26135         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
26136                 error "set striped dir error"
26137         #look at the directories for debug purposes
26138         ls -l $DIR/$tdir
26139         $LFS getdirstripe $DIR/$tdir
26140         ls -l $DIR/$tdir/remote_striped_dir
26141         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
26142         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
26143                 error "create 10 files failed"
26144
26145         for file in $(find $DIR/$tdir); do
26146                 stripe_count=$($LFS getstripe -c $file)
26147                 [ $stripe_count -eq 2 ] ||
26148                         error "wrong stripe $stripe_count for $file"
26149         done
26150
26151         rm -rf $DIR/$tdir
26152 }
26153 run_test 300d "check default stripe under striped directory"
26154
26155 test_300e() {
26156         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26157                 skip "Need MDS version at least 2.7.55"
26158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26160
26161         local stripe_count
26162         local file
26163
26164         mkdir -p $DIR/$tdir
26165
26166         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26167                 error "set striped dir error"
26168
26169         touch $DIR/$tdir/striped_dir/a
26170         touch $DIR/$tdir/striped_dir/b
26171         touch $DIR/$tdir/striped_dir/c
26172
26173         mkdir $DIR/$tdir/striped_dir/dir_a
26174         mkdir $DIR/$tdir/striped_dir/dir_b
26175         mkdir $DIR/$tdir/striped_dir/dir_c
26176
26177         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26178                 error "set striped adir under striped dir error"
26179
26180         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26181                 error "set striped bdir under striped dir error"
26182
26183         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26184                 error "set striped cdir under striped dir error"
26185
26186         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26187                 error "rename dir under striped dir fails"
26188
26189         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26190                 error "rename dir under different stripes fails"
26191
26192         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26193                 error "rename file under striped dir should succeed"
26194
26195         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26196                 error "rename dir under striped dir should succeed"
26197
26198         rm -rf $DIR/$tdir
26199 }
26200 run_test 300e "check rename under striped directory"
26201
26202 test_300f() {
26203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26204         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26205         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26206                 skip "Need MDS version at least 2.7.55"
26207
26208         local stripe_count
26209         local file
26210
26211         rm -rf $DIR/$tdir
26212         mkdir -p $DIR/$tdir
26213
26214         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26215                 error "set striped dir error"
26216
26217         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26218                 error "set striped dir error"
26219
26220         touch $DIR/$tdir/striped_dir/a
26221         mkdir $DIR/$tdir/striped_dir/dir_a
26222         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26223                 error "create striped dir under striped dir fails"
26224
26225         touch $DIR/$tdir/striped_dir1/b
26226         mkdir $DIR/$tdir/striped_dir1/dir_b
26227         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26228                 error "create striped dir under striped dir fails"
26229
26230         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26231                 error "rename dir under different striped dir should fail"
26232
26233         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26234                 error "rename striped dir under diff striped dir should fail"
26235
26236         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26237                 error "rename file under diff striped dirs fails"
26238
26239         rm -rf $DIR/$tdir
26240 }
26241 run_test 300f "check rename cross striped directory"
26242
26243 test_300_check_default_striped_dir()
26244 {
26245         local dirname=$1
26246         local default_count=$2
26247         local default_index=$3
26248         local stripe_count
26249         local stripe_index
26250         local dir_stripe_index
26251         local dir
26252
26253         echo "checking $dirname $default_count $default_index"
26254         $LFS setdirstripe -D -c $default_count -i $default_index \
26255                                 -H all_char $DIR/$tdir/$dirname ||
26256                 error "set default stripe on striped dir error"
26257         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26258         [ $stripe_count -eq $default_count ] ||
26259                 error "expect $default_count get $stripe_count for $dirname"
26260
26261         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26262         [ $stripe_index -eq $default_index ] ||
26263                 error "expect $default_index get $stripe_index for $dirname"
26264
26265         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26266                                                 error "create dirs failed"
26267
26268         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26269         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26270         for dir in $(find $DIR/$tdir/$dirname/*); do
26271                 stripe_count=$($LFS getdirstripe -c $dir)
26272                 (( $stripe_count == $default_count )) ||
26273                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26274                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26275                 error "stripe count $default_count != $stripe_count for $dir"
26276
26277                 stripe_index=$($LFS getdirstripe -i $dir)
26278                 [ $default_index -eq -1 ] ||
26279                         [ $stripe_index -eq $default_index ] ||
26280                         error "$stripe_index != $default_index for $dir"
26281
26282                 #check default stripe
26283                 stripe_count=$($LFS getdirstripe -D -c $dir)
26284                 [ $stripe_count -eq $default_count ] ||
26285                 error "default count $default_count != $stripe_count for $dir"
26286
26287                 stripe_index=$($LFS getdirstripe -D -i $dir)
26288                 [ $stripe_index -eq $default_index ] ||
26289                 error "default index $default_index != $stripe_index for $dir"
26290         done
26291         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26292 }
26293
26294 test_300g() {
26295         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26296         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26297                 skip "Need MDS version at least 2.7.55"
26298
26299         local dir
26300         local stripe_count
26301         local stripe_index
26302
26303         mkdir_on_mdt0 $DIR/$tdir
26304         mkdir $DIR/$tdir/normal_dir
26305
26306         #Checking when client cache stripe index
26307         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26308         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26309                 error "create striped_dir failed"
26310
26311         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26312                 error "create dir0 fails"
26313         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26314         [ $stripe_index -eq 0 ] ||
26315                 error "dir0 expect index 0 got $stripe_index"
26316
26317         mkdir $DIR/$tdir/striped_dir/dir1 ||
26318                 error "create dir1 fails"
26319         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26320         [ $stripe_index -eq 1 ] ||
26321                 error "dir1 expect index 1 got $stripe_index"
26322
26323         #check default stripe count/stripe index
26324         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26325         test_300_check_default_striped_dir normal_dir 1 0
26326         test_300_check_default_striped_dir normal_dir -1 1
26327         test_300_check_default_striped_dir normal_dir 2 -1
26328
26329         #delete default stripe information
26330         echo "delete default stripeEA"
26331         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26332                 error "set default stripe on striped dir error"
26333
26334         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26335         for dir in $(find $DIR/$tdir/normal_dir/*); do
26336                 stripe_count=$($LFS getdirstripe -c $dir)
26337                 [ $stripe_count -eq 0 ] ||
26338                         error "expect 1 get $stripe_count for $dir"
26339         done
26340 }
26341 run_test 300g "check default striped directory for normal directory"
26342
26343 test_300h() {
26344         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26345         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26346                 skip "Need MDS version at least 2.7.55"
26347
26348         local dir
26349         local stripe_count
26350
26351         mkdir $DIR/$tdir
26352         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26353                 error "set striped dir error"
26354
26355         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26356         test_300_check_default_striped_dir striped_dir 1 0
26357         test_300_check_default_striped_dir striped_dir -1 1
26358         test_300_check_default_striped_dir striped_dir 2 -1
26359
26360         #delete default stripe information
26361         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26362                 error "set default stripe on striped dir error"
26363
26364         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26365         for dir in $(find $DIR/$tdir/striped_dir/*); do
26366                 stripe_count=$($LFS getdirstripe -c $dir)
26367                 [ $stripe_count -eq 0 ] ||
26368                         error "expect 1 get $stripe_count for $dir"
26369         done
26370 }
26371 run_test 300h "check default striped directory for striped directory"
26372
26373 test_300i() {
26374         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26375         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26376         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26377                 skip "Need MDS version at least 2.7.55"
26378
26379         local stripe_count
26380         local file
26381
26382         mkdir $DIR/$tdir
26383
26384         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26385                 error "set striped dir error"
26386
26387         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26388                 error "create files under striped dir failed"
26389
26390         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26391                 error "set striped hashdir error"
26392
26393         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26394                 error "create dir0 under hash dir failed"
26395         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26396                 error "create dir1 under hash dir failed"
26397         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26398                 error "create dir2 under hash dir failed"
26399
26400         # unfortunately, we need to umount to clear dir layout cache for now
26401         # once we fully implement dir layout, we can drop this
26402         umount_client $MOUNT || error "umount failed"
26403         mount_client $MOUNT || error "mount failed"
26404
26405         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26406         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26407         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26408
26409         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26410                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26411                         error "create crush2 dir $tdir/hashdir/d3 failed"
26412                 $LFS find -H crush2 $DIR/$tdir/hashdir
26413                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26414                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26415
26416                 # mkdir with an invalid hash type (hash=fail_val) from client
26417                 # should be replaced on MDS with a valid (default) hash type
26418                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26419                 $LCTL set_param fail_loc=0x1901 fail_val=99
26420                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26421
26422                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26423                 local expect=$(do_facet mds1 \
26424                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26425                 [[ $hash == $expect ]] ||
26426                         error "d99 hash '$hash' != expected hash '$expect'"
26427         fi
26428
26429         #set the stripe to be unknown hash type on read
26430         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26431         $LCTL set_param fail_loc=0x1901 fail_val=99
26432         for ((i = 0; i < 10; i++)); do
26433                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26434                         error "stat f-$i failed"
26435                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26436         done
26437
26438         touch $DIR/$tdir/striped_dir/f0 &&
26439                 error "create under striped dir with unknown hash should fail"
26440
26441         $LCTL set_param fail_loc=0
26442
26443         umount_client $MOUNT || error "umount failed"
26444         mount_client $MOUNT || error "mount failed"
26445
26446         return 0
26447 }
26448 run_test 300i "client handle unknown hash type striped directory"
26449
26450 test_300j() {
26451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26453         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26454                 skip "Need MDS version at least 2.7.55"
26455
26456         local stripe_count
26457         local file
26458
26459         mkdir $DIR/$tdir
26460
26461         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26462         $LCTL set_param fail_loc=0x1702
26463         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26464                 error "set striped dir error"
26465
26466         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26467                 error "create files under striped dir failed"
26468
26469         $LCTL set_param fail_loc=0
26470
26471         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26472
26473         return 0
26474 }
26475 run_test 300j "test large update record"
26476
26477 test_300k() {
26478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26479         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26480         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26481                 skip "Need MDS version at least 2.7.55"
26482
26483         # this test needs a huge transaction
26484         local kb
26485         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26486              osd*.$FSNAME-MDT0000.kbytestotal")
26487         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26488
26489         local stripe_count
26490         local file
26491
26492         mkdir $DIR/$tdir
26493
26494         #define OBD_FAIL_LARGE_STRIPE   0x1703
26495         $LCTL set_param fail_loc=0x1703
26496         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26497                 error "set striped dir error"
26498         $LCTL set_param fail_loc=0
26499
26500         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26501                 error "getstripeddir fails"
26502         rm -rf $DIR/$tdir/striped_dir ||
26503                 error "unlink striped dir fails"
26504
26505         return 0
26506 }
26507 run_test 300k "test large striped directory"
26508
26509 test_300l() {
26510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26512         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26513                 skip "Need MDS version at least 2.7.55"
26514
26515         local stripe_index
26516
26517         test_mkdir -p $DIR/$tdir/striped_dir
26518         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26519                         error "chown $RUNAS_ID failed"
26520         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26521                 error "set default striped dir failed"
26522
26523         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26524         $LCTL set_param fail_loc=0x80000158
26525         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26526
26527         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26528         [ $stripe_index -eq 1 ] ||
26529                 error "expect 1 get $stripe_index for $dir"
26530 }
26531 run_test 300l "non-root user to create dir under striped dir with stale layout"
26532
26533 test_300m() {
26534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26535         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26536         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26537                 skip "Need MDS version at least 2.7.55"
26538
26539         mkdir -p $DIR/$tdir/striped_dir
26540         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26541                 error "set default stripes dir error"
26542
26543         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26544
26545         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26546         [ $stripe_count -eq 0 ] ||
26547                         error "expect 0 get $stripe_count for a"
26548
26549         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26550                 error "set default stripes dir error"
26551
26552         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26553
26554         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26555         [ $stripe_count -eq 0 ] ||
26556                         error "expect 0 get $stripe_count for b"
26557
26558         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26559                 error "set default stripes dir error"
26560
26561         mkdir $DIR/$tdir/striped_dir/c &&
26562                 error "default stripe_index is invalid, mkdir c should fails"
26563
26564         rm -rf $DIR/$tdir || error "rmdir fails"
26565 }
26566 run_test 300m "setstriped directory on single MDT FS"
26567
26568 cleanup_300n() {
26569         local list=$(comma_list $(mdts_nodes))
26570
26571         trap 0
26572         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26573 }
26574
26575 test_300n() {
26576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26578         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26579                 skip "Need MDS version at least 2.7.55"
26580         remote_mds_nodsh && skip "remote MDS with nodsh"
26581
26582         local stripe_index
26583         local list=$(comma_list $(mdts_nodes))
26584
26585         trap cleanup_300n RETURN EXIT
26586         mkdir -p $DIR/$tdir
26587         chmod 777 $DIR/$tdir
26588         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26589                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26590                 error "create striped dir succeeds with gid=0"
26591
26592         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26593         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26594                 error "create striped dir fails with gid=-1"
26595
26596         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26597         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26598                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26599                 error "set default striped dir succeeds with gid=0"
26600
26601
26602         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26603         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26604                 error "set default striped dir fails with gid=-1"
26605
26606
26607         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26608         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26609                                         error "create test_dir fails"
26610         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26611                                         error "create test_dir1 fails"
26612         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26613                                         error "create test_dir2 fails"
26614         cleanup_300n
26615 }
26616 run_test 300n "non-root user to create dir under striped dir with default EA"
26617
26618 test_300o() {
26619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26620         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26621         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26622                 skip "Need MDS version at least 2.7.55"
26623
26624         local numfree1
26625         local numfree2
26626
26627         mkdir -p $DIR/$tdir
26628
26629         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26630         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26631         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26632                 skip "not enough free inodes $numfree1 $numfree2"
26633         fi
26634
26635         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26636         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26637         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26638                 skip "not enough free space $numfree1 $numfree2"
26639         fi
26640
26641         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26642                 error "setdirstripe fails"
26643
26644         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26645                 error "create dirs fails"
26646
26647         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26648         ls $DIR/$tdir/striped_dir > /dev/null ||
26649                 error "ls striped dir fails"
26650         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26651                 error "unlink big striped dir fails"
26652 }
26653 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26654
26655 test_300p() {
26656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26658         remote_mds_nodsh && skip "remote MDS with nodsh"
26659
26660         mkdir_on_mdt0 $DIR/$tdir
26661
26662         #define OBD_FAIL_OUT_ENOSPC     0x1704
26663         do_facet mds2 lctl set_param fail_loc=0x80001704
26664         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26665                  && error "create striped directory should fail"
26666
26667         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26668
26669         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26670         true
26671 }
26672 run_test 300p "create striped directory without space"
26673
26674 test_300q() {
26675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26677
26678         local fd=$(free_fd)
26679         local cmd="exec $fd<$tdir"
26680         cd $DIR
26681         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26682         eval $cmd
26683         cmd="exec $fd<&-"
26684         trap "eval $cmd" EXIT
26685         cd $tdir || error "cd $tdir fails"
26686         rmdir  ../$tdir || error "rmdir $tdir fails"
26687         mkdir local_dir && error "create dir succeeds"
26688         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26689         eval $cmd
26690         return 0
26691 }
26692 run_test 300q "create remote directory under orphan directory"
26693
26694 test_300r() {
26695         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26696                 skip "Need MDS version at least 2.7.55" && return
26697         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26698
26699         mkdir $DIR/$tdir
26700
26701         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26702                 error "set striped dir error"
26703
26704         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26705                 error "getstripeddir fails"
26706
26707         local stripe_count
26708         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26709                       awk '/lmv_stripe_count:/ { print $2 }')
26710
26711         [ $MDSCOUNT -ne $stripe_count ] &&
26712                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26713
26714         rm -rf $DIR/$tdir/striped_dir ||
26715                 error "unlink striped dir fails"
26716 }
26717 run_test 300r "test -1 striped directory"
26718
26719 test_300s_helper() {
26720         local count=$1
26721
26722         local stripe_dir=$DIR/$tdir/striped_dir.$count
26723
26724         $LFS mkdir -c $count $stripe_dir ||
26725                 error "lfs mkdir -c error"
26726
26727         $LFS getdirstripe $stripe_dir ||
26728                 error "lfs getdirstripe fails"
26729
26730         local stripe_count
26731         stripe_count=$($LFS getdirstripe $stripe_dir |
26732                       awk '/lmv_stripe_count:/ { print $2 }')
26733
26734         [ $count -ne $stripe_count ] &&
26735                 error_noexit "bad stripe count $stripe_count expected $count"
26736
26737         local dupe_stripes
26738         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26739                 awk '/0x/ {count[$1] += 1}; END {
26740                         for (idx in count) {
26741                                 if (count[idx]>1) {
26742                                         print "index " idx " count " count[idx]
26743                                 }
26744                         }
26745                 }')
26746
26747         if [[ -n "$dupe_stripes" ]] ; then
26748                 lfs getdirstripe $stripe_dir
26749                 error_noexit "Dupe MDT above: $dupe_stripes "
26750         fi
26751
26752         rm -rf $stripe_dir ||
26753                 error_noexit "unlink $stripe_dir fails"
26754 }
26755
26756 test_300s() {
26757         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26758                 skip "Need MDS version at least 2.7.55" && return
26759         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26760
26761         mkdir $DIR/$tdir
26762         for count in $(seq 2 $MDSCOUNT); do
26763                 test_300s_helper $count
26764         done
26765 }
26766 run_test 300s "test lfs mkdir -c without -i"
26767
26768 test_300t() {
26769         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26770                 skip "need MDS 2.14.55 or later"
26771         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26772
26773         local testdir="$DIR/$tdir/striped_dir"
26774         local dir1=$testdir/dir1
26775         local dir2=$testdir/dir2
26776
26777         mkdir -p $testdir
26778
26779         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26780                 error "failed to set default stripe count for $testdir"
26781
26782         mkdir $dir1
26783         local stripe_count=$($LFS getdirstripe -c $dir1)
26784
26785         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26786
26787         local max_count=$((MDSCOUNT - 1))
26788         local mdts=$(comma_list $(mdts_nodes))
26789
26790         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26791         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26792
26793         mkdir $dir2
26794         stripe_count=$($LFS getdirstripe -c $dir2)
26795
26796         (( $stripe_count == $max_count )) || error "wrong stripe count"
26797 }
26798 run_test 300t "test max_mdt_stripecount"
26799
26800 MDT_OVSTRP_VER="2.15.60"
26801 # 300u family tests MDT overstriping
26802 test_300ua() {
26803         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26804
26805         local setcount=$((MDSCOUNT * 2))
26806
26807         local expected_count
26808
26809         mkdir $DIR/$tdir
26810         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26811                 error "(0) failed basic overstriped dir creation test"
26812         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26813
26814         # This does a basic interop test - if the MDS does not support mdt
26815         # overstriping, we should get stripes == number of MDTs
26816         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26817                 expected_count=$MDSCOUNT
26818         else
26819                 expected_count=$setcount
26820         fi
26821         (( getstripe_count == expected_count )) ||
26822                 error "(1) incorrect stripe count for simple overstriped dir"
26823
26824         rm -rf $DIR/$tdir/${tdir}.0 ||
26825                 error "(2) unable to rm overstriped dir"
26826
26827         # Tests after this require overstriping support
26828         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26829                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26830
26831         test_striped_dir 0 $setcount true ||
26832                 error "(3)failed on overstriped dir"
26833         test_striped_dir 1 $setcount true ||
26834                 error "(4)failed on overstriped dir"
26835
26836         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26837
26838         test_striped_dir 0 $setcount true ||
26839                 error "(5)failed on overstriped dir"
26840 }
26841 run_test 300ua "basic overstriped dir sanity test"
26842
26843 test_300ub() {
26844         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26845                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26846         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26847
26848         mkdir $DIR/$tdir
26849
26850         echo "Testing invalid stripe count, failure expected"
26851         local setcount=$((MDSCOUNT * 2))
26852
26853         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26854         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26855
26856         (( getstripe_count <= MDSCOUNT )) ||
26857                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26858
26859         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26860         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26861         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26862
26863         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26864
26865         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26866         (( getstripe_count == maxcount )) ||
26867                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26868
26869         # Test specific striping with -i
26870         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26871
26872         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26873         (( getstripe_count == 4 )) ||
26874                 error "(2)stripe_count is $getstripe_count, expect 4"
26875
26876         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26877                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26878
26879         [[ -n "$nonzeroindices" ]] ||
26880                 error "(3) stripes indices not all 0: $nonzeroindices"
26881
26882         # Test specific striping with too many stripes on one MDT
26883         echo "Testing invalid striping, failure expected"
26884         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26885         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26886         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26887                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26888         echo "stripes on MDT0: $getstripe_count"
26889         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26890                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26891
26892         setcount=$((MDSCOUNT * 2))
26893         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26894                 error "(5) can't setdirstripe with manually set hash function"
26895
26896         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26897         (( getstripe_count == setcount )) ||
26898                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26899
26900         setcount=$((MDSCOUNT * 2))
26901         mkdir $DIR/${tdir}.5
26902         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26903                 error "(7) can't setdirstripe with manually set hash function"
26904         mkdir $DIR/${tdir}.5/${tdir}.6
26905
26906         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26907         (( getstripe_count == setcount )) ||
26908                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26909 }
26910 run_test 300ub "test MDT overstriping interface & limits"
26911
26912 test_300uc() {
26913         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26914                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26915         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26916
26917         mkdir $DIR/$tdir
26918
26919         local setcount=$((MDSCOUNT * 2))
26920
26921         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26922
26923         mkdir $DIR/$tdir/${tdir}.1
26924
26925         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26926
26927         (( getstripe_count == setcount )) ||
26928                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26929
26930         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26931
26932         local getstripe_count=$($LFS getdirstripe -c \
26933                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26934
26935         (( getstripe_count == setcount )) ||
26936                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26937 }
26938 run_test 300uc "test MDT overstriping as default & inheritance"
26939
26940 test_300ud() {
26941         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26942                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26943         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26944
26945         local mdts=$(comma_list $(mdts_nodes))
26946         local timeout=100
26947
26948         local restripe_status
26949         local delta
26950         local i
26951
26952         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26953
26954         # in case "crush" hash type is not set
26955         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26956
26957         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26958                            mdt.*MDT0000.enable_dir_restripe)
26959         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26960         stack_trap "do_nodes $mdts $LCTL set_param \
26961                     mdt.*.enable_dir_restripe=$restripe_status"
26962
26963         mkdir $DIR/$tdir
26964         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26965                 error "create files under remote dir failed $i"
26966         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26967                 error "create dirs under remote dir failed $i"
26968
26969         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26970
26971         (( setcount < 13 )) || setcount=12
26972         for i in $(seq 2 $setcount); do
26973                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26974                 $LFS setdirstripe -C $i $DIR/$tdir ||
26975                         error "split -C $i $tdir failed"
26976                 wait_update $HOSTNAME \
26977                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26978                         error "dir split not finished"
26979                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26980                         awk '/migrate/ {sum += $2} END { print sum }')
26981                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26982                 # delta is around total_files/stripe_count, deviation 3%
26983                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26984                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26985         done
26986 }
26987 run_test 300ud "dir split"
26988
26989 test_300ue() {
26990         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26991                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26992         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26993
26994         local mdts=$(comma_list $(mdts_nodes))
26995         local timeout=100
26996
26997         local restripe_status
26998         local delta
26999         local c
27000
27001         [[ $mds1_FSTYPE == zfs ]] && timeout=300
27002
27003         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
27004
27005         restripe_status=$(do_facet mds1 $LCTL get_param -n \
27006                            mdt.*MDT0000.enable_dir_restripe)
27007         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
27008         stack_trap "do_nodes $mdts $LCTL set_param \
27009                     mdt.*.enable_dir_restripe=$restripe_status"
27010
27011         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27012
27013         (( setcount < 13 )) || setcount=12
27014         test_mkdir -C $setcount -H crush $DIR/$tdir
27015         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
27016                 error "create files under remote dir failed"
27017         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
27018                 error "create dirs under remote dir failed"
27019
27020         for c in $(seq $((setcount - 1)) -1 1); do
27021                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
27022                 $LFS setdirstripe -C $c $DIR/$tdir ||
27023                         error "split -C $c $tdir failed"
27024                 wait_update $HOSTNAME \
27025                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
27026                         error "dir merge not finished"
27027                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
27028                         awk '/migrate/ {sum += $2} END { print sum }')
27029                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
27030                 # delta is around total_files/stripe_count, deviation 3%
27031                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
27032                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
27033         done
27034 }
27035 run_test 300ue "dir merge"
27036
27037 test_300uf() {
27038         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
27039                 skip "skipped for MDS < $MDT_OVSTRP_VER"
27040         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27041
27042         # maximum amount of local locks:
27043         # parent striped dir - 2 locks
27044         # new stripe in parent to migrate to - 1 lock
27045         # source and target - 2 locks
27046         # Total 5 locks for regular file
27047         #
27048         # NB: Overstriping should add several extra local locks
27049         # FIXME: Remove this once understood
27050         #lctl set_param *debug=-1 debug_mb=10000
27051         lctl clear
27052         lctl mark "touch/create"
27053         mkdir -p $DIR/$tdir
27054         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27055         local setcount=$((MDSCOUNT * 5))
27056
27057         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
27058         touch $DIR/$tdir/dir1/eee
27059
27060         lctl mark "hardlinks"
27061         # create 4 hardlink for 4 more locks
27062         # Total: 9 locks > RS_MAX_LOCKS (8)
27063         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
27064         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
27065         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
27066         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
27067         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
27068         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
27069         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
27070         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
27071
27072         lctl mark "cancel lru"
27073         cancel_lru_locks mdc
27074
27075         lctl mark "migrate"
27076         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
27077                 error "migrate dir fails"
27078
27079         rm -rf $DIR/$tdir || error "rm dir failed after migration"
27080 }
27081 run_test 300uf "migrate with too many local locks"
27082
27083 test_300ug() {
27084         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
27085                 skip "skipped for MDS < $MDT_OVSTRP_VER"
27086         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27087
27088         mkdir -p $DIR/$tdir
27089         local migrate_dir=$DIR/$tdir/migrate_dir
27090         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27091         local setcount2=$((setcount - 2))
27092
27093         $LFS setdirstripe -c 2 $migrate_dir ||
27094                 error "(0) failed to create striped directory"
27095
27096         $LFS migrate -m 0 -C $setcount $migrate_dir ||
27097                 error "(1)failed to migrate to overstriped directory"
27098         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27099
27100         (( getstripe_count == setcount )) ||
27101                 error "(2)stripe_count is $getstripe_count, expect $setcount"
27102         touch $DIR/$tdir/migrate_dir/$tfile ||
27103                 error "(3)failed to create file in overstriped directory"
27104         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
27105                 error "(4)failed to migrate overstriped directory"
27106         # Check stripe count after migration
27107         $LFS getdirstripe $migrate_dir
27108         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27109         (( getstripe_count == setcount2 )) ||
27110                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
27111
27112         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
27113 }
27114 run_test 300ug "migrate overstriped dirs"
27115
27116 prepare_remote_file() {
27117         mkdir $DIR/$tdir/src_dir ||
27118                 error "create remote source failed"
27119
27120         cp /etc/hosts $DIR/$tdir/src_dir/a ||
27121                  error "cp to remote source failed"
27122         touch $DIR/$tdir/src_dir/a
27123
27124         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
27125                 error "create remote target dir failed"
27126
27127         touch $DIR/$tdir/tgt_dir/b
27128
27129         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
27130                 error "rename dir cross MDT failed!"
27131
27132         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
27133                 error "src_child still exists after rename"
27134
27135         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
27136                 error "missing file(a) after rename"
27137
27138         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
27139                 error "diff after rename"
27140 }
27141
27142 test_310a() {
27143         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27145
27146         local remote_file=$DIR/$tdir/tgt_dir/b
27147
27148         mkdir -p $DIR/$tdir
27149
27150         prepare_remote_file || error "prepare remote file failed"
27151
27152         #open-unlink file
27153         $OPENUNLINK $remote_file $remote_file ||
27154                 error "openunlink $remote_file failed"
27155         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27156 }
27157 run_test 310a "open unlink remote file"
27158
27159 test_310b() {
27160         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27162
27163         local remote_file=$DIR/$tdir/tgt_dir/b
27164
27165         mkdir -p $DIR/$tdir
27166
27167         prepare_remote_file || error "prepare remote file failed"
27168
27169         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27170         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27171         $CHECKSTAT -t file $remote_file || error "check file failed"
27172 }
27173 run_test 310b "unlink remote file with multiple links while open"
27174
27175 test_310c() {
27176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27177         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27178
27179         local remote_file=$DIR/$tdir/tgt_dir/b
27180
27181         mkdir -p $DIR/$tdir
27182
27183         prepare_remote_file || error "prepare remote file failed"
27184
27185         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27186         multiop_bg_pause $remote_file O_uc ||
27187                         error "mulitop failed for remote file"
27188         MULTIPID=$!
27189         $MULTIOP $DIR/$tfile Ouc
27190         kill -USR1 $MULTIPID
27191         wait $MULTIPID
27192 }
27193 run_test 310c "open-unlink remote file with multiple links"
27194
27195 #LU-4825
27196 test_311() {
27197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27198         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27199         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27200                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27201         remote_mds_nodsh && skip "remote MDS with nodsh"
27202
27203         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27204         local mdts=$(comma_list $(mdts_nodes))
27205
27206         mkdir -p $DIR/$tdir
27207         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27208         createmany -o $DIR/$tdir/$tfile. 1000
27209
27210         # statfs data is not real time, let's just calculate it
27211         old_iused=$((old_iused + 1000))
27212
27213         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27214                         osp.*OST0000*MDT0000.create_count")
27215         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27216                                 osp.*OST0000*MDT0000.max_create_count")
27217         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27218
27219         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27220         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27221         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27222
27223         unlinkmany $DIR/$tdir/$tfile. 1000
27224
27225         do_nodes $mdts "$LCTL set_param -n \
27226                         osp.*OST0000*.max_create_count=$max_count"
27227         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27228                 do_nodes $mdts "$LCTL set_param -n \
27229                                 osp.*OST0000*.create_count=$count"
27230         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27231                         grep "=0" && error "create_count is zero"
27232
27233         local new_iused
27234         for i in $(seq 120); do
27235                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27236                 # system may be too busy to destroy all objs in time, use
27237                 # a somewhat small value to not fail autotest
27238                 [ $((old_iused - new_iused)) -gt 400 ] && break
27239                 sleep 1
27240         done
27241
27242         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27243         [ $((old_iused - new_iused)) -gt 400 ] ||
27244                 error "objs not destroyed after unlink"
27245 }
27246 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27247
27248 zfs_get_objid()
27249 {
27250         local ost=$1
27251         local tf=$2
27252         local fid=($($LFS getstripe $tf | grep 0x))
27253         local seq=${fid[3]#0x}
27254         local objid=${fid[1]}
27255
27256         local vdevdir=$(dirname $(facet_vdevice $ost))
27257         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27258         local zfs_zapid=$(do_facet $ost $cmd |
27259                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27260                           awk '/Object/{getline; print $1}')
27261         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27262                           awk "/$objid = /"'{printf $3}')
27263
27264         echo $zfs_objid
27265 }
27266
27267 zfs_object_blksz() {
27268         local ost=$1
27269         local objid=$2
27270
27271         local vdevdir=$(dirname $(facet_vdevice $ost))
27272         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27273         local blksz=$(do_facet $ost $cmd $objid |
27274                       awk '/dblk/{getline; printf $4}')
27275
27276         case "${blksz: -1}" in
27277                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27278                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27279                 *) ;;
27280         esac
27281
27282         echo $blksz
27283 }
27284
27285 test_312() { # LU-4856
27286         remote_ost_nodsh && skip "remote OST with nodsh"
27287         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27288
27289         local max_blksz=$(do_facet ost1 \
27290                           $ZFS get -p recordsize $(facet_device ost1) |
27291                           awk '!/VALUE/{print $3}')
27292         local tf=$DIR/$tfile
27293
27294         $LFS setstripe -c1 $tf
27295         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27296
27297         # Get ZFS object id
27298         local zfs_objid=$(zfs_get_objid $facet $tf)
27299         # block size change by sequential overwrite
27300         local bs
27301
27302         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27303                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27304
27305                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27306                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27307         done
27308         rm -f $tf
27309
27310         $LFS setstripe -c1 $tf
27311         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27312
27313         # block size change by sequential append write
27314         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27315         zfs_objid=$(zfs_get_objid $facet $tf)
27316         local count
27317
27318         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27319                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27320                         oflag=sync conv=notrunc
27321
27322                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27323                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27324                         error "blksz error, actual $blksz, " \
27325                                 "expected: 2 * $count * $PAGE_SIZE"
27326         done
27327         rm -f $tf
27328
27329         # random write
27330         $LFS setstripe -c1 $tf
27331         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27332         zfs_objid=$(zfs_get_objid $facet $tf)
27333
27334         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27335         blksz=$(zfs_object_blksz $facet $zfs_objid)
27336         (( blksz == PAGE_SIZE )) ||
27337                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27338
27339         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27340         blksz=$(zfs_object_blksz $facet $zfs_objid)
27341         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27342
27343         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27344         blksz=$(zfs_object_blksz $facet $zfs_objid)
27345         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27346 }
27347 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27348
27349 test_313() {
27350         remote_ost_nodsh && skip "remote OST with nodsh"
27351
27352         local file=$DIR/$tfile
27353
27354         rm -f $file
27355         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27356
27357         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27358         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27359         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27360                 error "write should failed"
27361         do_facet ost1 "$LCTL set_param fail_loc=0"
27362         rm -f $file
27363 }
27364 run_test 313 "io should fail after last_rcvd update fail"
27365
27366 test_314() {
27367         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27368
27369         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27370         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27371         rm -f $DIR/$tfile
27372         wait_delete_completed
27373         do_facet ost1 "$LCTL set_param fail_loc=0"
27374 }
27375 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27376
27377 test_315() { # LU-618
27378         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27379
27380         local file=$DIR/$tfile
27381         rm -f $file
27382
27383         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27384                 error "multiop file write failed"
27385         $MULTIOP $file oO_RDONLY:r4063232_c &
27386         PID=$!
27387
27388         sleep 2
27389
27390         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27391         kill -USR1 $PID
27392
27393         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27394         rm -f $file
27395 }
27396 run_test 315 "read should be accounted"
27397
27398 test_316() {
27399         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27400         large_xattr_enabled || skip "ea_inode feature disabled"
27401
27402         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27403         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27404         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27405         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27406
27407         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27408 }
27409 run_test 316 "lfs migrate of file with large_xattr enabled"
27410
27411 test_317() {
27412         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27413                 skip "Need MDS version at least 2.11.53"
27414         if [ "$ost1_FSTYPE" == "zfs" ]; then
27415                 skip "LU-10370: no implementation for ZFS"
27416         fi
27417
27418         local trunc_sz
27419         local grant_blk_size
27420
27421         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27422                         awk '/grant_block_size:/ { print $2; exit; }')
27423         #
27424         # Create File of size 5M. Truncate it to below size's and verify
27425         # blocks count.
27426         #
27427         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27428                 error "Create file $DIR/$tfile failed"
27429         stack_trap "rm -f $DIR/$tfile" EXIT
27430
27431         for trunc_sz in 2097152 4097 4000 509 0; do
27432                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27433                         error "truncate $tfile to $trunc_sz failed"
27434                 local sz=$(stat --format=%s $DIR/$tfile)
27435                 local blk=$(stat --format=%b $DIR/$tfile)
27436                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27437                                      grant_blk_size) * 8))
27438
27439                 if [[ $blk -ne $trunc_blk ]]; then
27440                         $(which stat) $DIR/$tfile
27441                         error "Expected Block $trunc_blk got $blk for $tfile"
27442                 fi
27443
27444                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27445                         error "Expected Size $trunc_sz got $sz for $tfile"
27446         done
27447
27448         #
27449         # sparse file test
27450         # Create file with a hole and write actual 65536 bytes which aligned
27451         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27452         #
27453         local bs=65536
27454         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27455                 error "Create file : $DIR/$tfile"
27456
27457         #
27458         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27459         # blocks. The block count must drop to 8.
27460         #
27461         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27462                 ((bs - grant_blk_size) + 1)))
27463         $TRUNCATE $DIR/$tfile $trunc_sz ||
27464                 error "truncate $tfile to $trunc_sz failed"
27465
27466         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27467         sz=$(stat --format=%s $DIR/$tfile)
27468         blk=$(stat --format=%b $DIR/$tfile)
27469
27470         if [[ $blk -ne $trunc_bsz ]]; then
27471                 $(which stat) $DIR/$tfile
27472                 error "Expected Block $trunc_bsz got $blk for $tfile"
27473         fi
27474
27475         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27476                 error "Expected Size $trunc_sz got $sz for $tfile"
27477 }
27478 run_test 317 "Verify blocks get correctly update after truncate"
27479
27480 test_318() {
27481         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27482         local old_max_active=$($LCTL get_param -n \
27483                             ${llite_name}.max_read_ahead_async_active \
27484                             2>/dev/null)
27485
27486         $LCTL set_param llite.*.max_read_ahead_async_active=256
27487         local max_active=$($LCTL get_param -n \
27488                            ${llite_name}.max_read_ahead_async_active \
27489                            2>/dev/null)
27490         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27491
27492         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27493                 error "set max_read_ahead_async_active should succeed"
27494
27495         $LCTL set_param llite.*.max_read_ahead_async_active=512
27496         max_active=$($LCTL get_param -n \
27497                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27498         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27499
27500         # restore @max_active
27501         [ $old_max_active -ne 0 ] && $LCTL set_param \
27502                 llite.*.max_read_ahead_async_active=$old_max_active
27503
27504         local old_threshold=$($LCTL get_param -n \
27505                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27506         local max_per_file_mb=$($LCTL get_param -n \
27507                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27508
27509         local invalid=$(($max_per_file_mb + 1))
27510         $LCTL set_param \
27511                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27512                         && error "set $invalid should fail"
27513
27514         local valid=$(($invalid - 1))
27515         $LCTL set_param \
27516                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27517                         error "set $valid should succeed"
27518         local threshold=$($LCTL get_param -n \
27519                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27520         [ $threshold -eq $valid ] || error \
27521                 "expect threshold $valid got $threshold"
27522         $LCTL set_param \
27523                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27524 }
27525 run_test 318 "Verify async readahead tunables"
27526
27527 test_319() {
27528         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27529
27530         local before=$(date +%s)
27531         local evict
27532         local mdir=$DIR/$tdir
27533         local file=$mdir/xxx
27534
27535         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27536         touch $file
27537
27538 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27539         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27540         $LFS migrate -m1 $mdir &
27541
27542         sleep 1
27543         dd if=$file of=/dev/null
27544         wait
27545         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27546           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27547
27548         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27549 }
27550 run_test 319 "lost lease lock on migrate error"
27551
27552 test_350() {
27553         local mdts=$(comma_list $(mdts_nodes))
27554
27555         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27556         stack_trap "rm -r $DIR/$tdir"
27557
27558         #force 1/100 of replies to take "NID mismatch" codepath
27559         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27560         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27561
27562         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27563         stack_trap "killall -9 ls || killall -9 ls"
27564
27565         cp -a /etc $DIR/$tdir || error "cp failed"
27566 }
27567 run_test 350 "force NID mismatch path to be exercised"
27568
27569 test_360() {
27570         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27571                 skip "Need OST version at least 2.15.58.96"
27572         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27573
27574         check_set_fallocate_or_skip
27575         local param="osd-ldiskfs.delayed_unlink_mb"
27576         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27577
27578         do_facet ost1 "$LCTL set_param $param=1MiB"
27579         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27580
27581         mkdir $DIR/$tdir/
27582         do_facet ost1 $LCTL set_param debug=+inode
27583         do_facet ost1 $LCTL clear
27584         local files=100
27585
27586         for ((i = 0; i < $files; i++)); do
27587                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27588                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27589         done
27590         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27591
27592         for ((i = 0; i < $files; i++)); do
27593                 unlink $DIR/$tdir/$tfile.$i ||
27594                         error "unlink $DIR/$tdir/$tfile.$i failed"
27595         done
27596
27597         local count=0
27598         local loop
27599
27600         for (( loop = 0; loop < 30 && count < min; loop++)); do
27601                 sleep 1
27602                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27603                 echo "Count[$loop]: $count"
27604         done
27605         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27606 }
27607 run_test 360 "ldiskfs unlink in a separate thread"
27608
27609 test_398a() { # LU-4198
27610         local ost1_imp=$(get_osc_import_name client ost1)
27611         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27612                          cut -d'.' -f2)
27613
27614         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27615         stack_trap "rm -f $DIR/$tfile"
27616         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27617
27618         # request a new lock on client
27619         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27620
27621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27622         local lock_count=$($LCTL get_param -n \
27623                            ldlm.namespaces.$imp_name.lru_size)
27624         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27625
27626         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27627
27628         # no lock cached, should use lockless DIO and not enqueue new lock
27629         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27630         lock_count=$($LCTL get_param -n \
27631                      ldlm.namespaces.$imp_name.lru_size)
27632         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27633
27634         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27635
27636         # no lock cached, should use locked DIO append
27637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27638                 conv=notrunc || error "DIO append failed"
27639         lock_count=$($LCTL get_param -n \
27640                      ldlm.namespaces.$imp_name.lru_size)
27641         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27642 }
27643 run_test 398a "direct IO should cancel lock otherwise lockless"
27644
27645 test_398b() { # LU-4198
27646         local before=$(date +%s)
27647         local njobs=4
27648         local size=48
27649
27650         which fio || skip_env "no fio installed"
27651         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27652         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27653
27654         # Single page, multiple pages, stripe size, 4*stripe size
27655         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27656                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27657                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27658                         --numjobs=$njobs --fallocate=none \
27659                         --iodepth=16 --allow_file_create=0 \
27660                         --size=$((size/njobs))M \
27661                         --filename=$DIR/$tfile &
27662                 bg_pid=$!
27663
27664                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27665                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27666                         --numjobs=$njobs --fallocate=none \
27667                         --iodepth=16 --allow_file_create=0 \
27668                         --size=$((size/njobs))M \
27669                         --filename=$DIR/$tfile || true
27670                 wait $bg_pid
27671         done
27672
27673         evict=$(do_facet client $LCTL get_param \
27674                 osc.$FSNAME-OST*-osc-*/state |
27675             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27676
27677         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27678                 (do_facet client $LCTL get_param \
27679                         osc.$FSNAME-OST*-osc-*/state;
27680                     error "eviction happened: $evict before:$before")
27681
27682         rm -f $DIR/$tfile
27683 }
27684 run_test 398b "DIO and buffer IO race"
27685
27686 test_398c() { # LU-4198
27687         local ost1_imp=$(get_osc_import_name client ost1)
27688         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27689                          cut -d'.' -f2)
27690
27691         which fio || skip_env "no fio installed"
27692
27693         saved_debug=$($LCTL get_param -n debug)
27694         $LCTL set_param debug=0
27695
27696         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27697         ((size /= 1024)) # by megabytes
27698         ((size /= 2)) # write half of the OST at most
27699         [ $size -gt 40 ] && size=40 #reduce test time anyway
27700
27701         $LFS setstripe -c 1 $DIR/$tfile
27702
27703         # it seems like ldiskfs reserves more space than necessary if the
27704         # writing blocks are not mapped, so it extends the file firstly
27705         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27706         cancel_lru_locks osc
27707
27708         # clear and verify rpc_stats later
27709         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27710
27711         local njobs=4
27712         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27713         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27714                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27715                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27716                 --filename=$DIR/$tfile
27717         [ $? -eq 0 ] || error "fio write error"
27718
27719         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27720                 error "Locks were requested while doing AIO"
27721
27722         # get the percentage of 1-page I/O
27723         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27724                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27725                 awk '{print $7}')
27726         (( $pct <= 50 )) || {
27727                 $LCTL get_param osc.${imp_name}.rpc_stats
27728                 error "$pct% of I/O are 1-page"
27729         }
27730
27731         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27732         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27733                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27734                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27735                 --filename=$DIR/$tfile
27736         [ $? -eq 0 ] || error "fio mixed read write error"
27737
27738         echo "AIO with large block size ${size}M"
27739         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27740                 --numjobs=1 --fallocate=none --ioengine=libaio \
27741                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27742                 --filename=$DIR/$tfile
27743         [ $? -eq 0 ] || error "fio large block size failed"
27744
27745         rm -f $DIR/$tfile
27746         $LCTL set_param debug="$saved_debug"
27747 }
27748 run_test 398c "run fio to test AIO"
27749
27750 test_398d() { #  LU-13846
27751         which aiocp || skip_env "no aiocp installed"
27752         local aio_file=$DIR/$tfile.aio
27753
27754         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27755
27756         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27757         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27758         stack_trap "rm -f $DIR/$tfile $aio_file"
27759
27760         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27761
27762         # test memory unaligned aio
27763         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27764                 error "unaligned aio failed"
27765         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27766
27767         rm -f $DIR/$tfile $aio_file
27768 }
27769 run_test 398d "run aiocp to verify block size > stripe size"
27770
27771 test_398e() {
27772         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27773         touch $DIR/$tfile.new
27774         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27775 }
27776 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27777
27778 test_398f() { #  LU-14687
27779         which aiocp || skip_env "no aiocp installed"
27780         local aio_file=$DIR/$tfile.aio
27781
27782         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27783
27784         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27785         stack_trap "rm -f $DIR/$tfile $aio_file"
27786
27787         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27788         $LCTL set_param fail_loc=0x1418
27789         # make sure we don't crash and fail properly
27790         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27791                 error "aio with page allocation failure succeeded"
27792         $LCTL set_param fail_loc=0
27793         diff $DIR/$tfile $aio_file
27794         [[ $? != 0 ]] || error "no diff after failed aiocp"
27795 }
27796 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27797
27798 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27799 # stripe and i/o size must be > stripe size
27800 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27801 # single RPC in flight.  This test shows async DIO submission is working by
27802 # showing multiple RPCs in flight.
27803 test_398g() { #  LU-13798
27804         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27805
27806         # We need to do some i/o first to acquire enough grant to put our RPCs
27807         # in flight; otherwise a new connection may not have enough grant
27808         # available
27809         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27810                 error "parallel dio failed"
27811         stack_trap "rm -f $DIR/$tfile"
27812
27813         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27814         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27815         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27816         stack_trap "$LCTL set_param -n $pages_per_rpc"
27817
27818         # Recreate file so it's empty
27819         rm -f $DIR/$tfile
27820         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27821         #Pause rpc completion to guarantee we see multiple rpcs in flight
27822         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27823         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27824         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27825
27826         # Clear rpc stats
27827         $LCTL set_param osc.*.rpc_stats=c
27828
27829         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27830                 error "parallel dio failed"
27831         stack_trap "rm -f $DIR/$tfile"
27832
27833         $LCTL get_param osc.*-OST0000-*.rpc_stats
27834         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27835                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27836                 grep "8:" | awk '{print $8}')
27837         # We look at the "8 rpcs in flight" field, and verify A) it is present
27838         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27839         # as expected for an 8M DIO to a file with 1M stripes.
27840         # NB: There is occasionally a mystery extra write RPC to a different
27841         # file.  I can't identify why that's happening, so we set up a margin
27842         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27843         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27844
27845         # Verify turning off parallel dio works as expected
27846         # Clear rpc stats
27847         $LCTL set_param osc.*.rpc_stats=c
27848         $LCTL set_param llite.*.parallel_dio=0
27849         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27850
27851         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27852                 error "dio with parallel dio disabled failed"
27853
27854         # Ideally, we would see only one RPC in flight here, but there is an
27855         # unavoidable race between i/o completion and RPC in flight counting,
27856         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27857         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27858         # So instead we just verify it's always < 8.
27859         $LCTL get_param osc.*-OST0000-*.rpc_stats
27860         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27861                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27862                 grep '^$' -B1 | grep . | awk '{print $1}')
27863         [ $ret != "8:" ] ||
27864                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27865 }
27866 run_test 398g "verify parallel dio async RPC submission"
27867
27868 test_398h() { #  LU-13798
27869         local dio_file=$DIR/$tfile.dio
27870
27871         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27872
27873         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27874         stack_trap "rm -f $DIR/$tfile $dio_file"
27875
27876         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27877                 error "parallel dio failed"
27878         diff $DIR/$tfile $dio_file
27879         [[ $? == 0 ]] || error "file diff after aiocp"
27880 }
27881 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27882
27883 test_398i() { #  LU-13798
27884         local dio_file=$DIR/$tfile.dio
27885
27886         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27887
27888         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27889         stack_trap "rm -f $DIR/$tfile $dio_file"
27890
27891         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27892         $LCTL set_param fail_loc=0x1418
27893         # make sure we don't crash and fail properly
27894         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27895                 error "parallel dio page allocation failure succeeded"
27896         diff $DIR/$tfile $dio_file
27897         [[ $? != 0 ]] || error "no diff after failed aiocp"
27898 }
27899 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27900
27901 test_398j() { #  LU-13798
27902         # Stripe size > RPC size but less than i/o size tests split across
27903         # stripes and RPCs for individual i/o op
27904         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27905
27906         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27907         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27908         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27909         stack_trap "$LCTL set_param -n $pages_per_rpc"
27910
27911         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27912                 error "parallel dio write failed"
27913         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27914
27915         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27916                 error "parallel dio read failed"
27917         diff $DIR/$tfile $DIR/$tfile.2
27918         [[ $? == 0 ]] || error "file diff after parallel dio read"
27919 }
27920 run_test 398j "test parallel dio where stripe size > rpc_size"
27921
27922 test_398k() { #  LU-13798
27923         wait_delete_completed
27924         wait_mds_ost_sync
27925
27926         # 4 stripe file; we will cause out of space on OST0
27927         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27928
27929         # Fill OST0 (if it's not too large)
27930         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27931                    head -n1)
27932         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27933                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27934         fi
27935         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27936         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27937                 error "dd should fill OST0"
27938         stack_trap "rm -f $DIR/$tfile.1"
27939
27940         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27941         err=$?
27942
27943         ls -la $DIR/$tfile
27944         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27945                 error "file is not 0 bytes in size"
27946
27947         # dd above should not succeed, but don't error until here so we can
27948         # get debug info above
27949         [[ $err != 0 ]] ||
27950                 error "parallel dio write with enospc succeeded"
27951         stack_trap "rm -f $DIR/$tfile"
27952 }
27953 run_test 398k "test enospc on first stripe"
27954
27955 test_398l() { #  LU-13798
27956         wait_delete_completed
27957         wait_mds_ost_sync
27958
27959         # 4 stripe file; we will cause out of space on OST0
27960         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27961         # happens on the second i/o chunk we issue
27962         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27963
27964         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27965         stack_trap "rm -f $DIR/$tfile"
27966
27967         # Fill OST0 (if it's not too large)
27968         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27969                    head -n1)
27970         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27971                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27972         fi
27973         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27974         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27975                 error "dd should fill OST0"
27976         stack_trap "rm -f $DIR/$tfile.1"
27977
27978         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27979         err=$?
27980         stack_trap "rm -f $DIR/$tfile.2"
27981
27982         # Check that short write completed as expected
27983         ls -la $DIR/$tfile.2
27984         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27985                 error "file is not 1M in size"
27986
27987         # dd above should not succeed, but don't error until here so we can
27988         # get debug info above
27989         [[ $err != 0 ]] ||
27990                 error "parallel dio write with enospc succeeded"
27991
27992         # Truncate source file to same length as output file and diff them
27993         $TRUNCATE $DIR/$tfile 1048576
27994         diff $DIR/$tfile $DIR/$tfile.2
27995         [[ $? == 0 ]] || error "data incorrect after short write"
27996 }
27997 run_test 398l "test enospc on intermediate stripe/RPC"
27998
27999 test_398m() { #  LU-13798
28000         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
28001
28002         # Set up failure on OST0, the first stripe:
28003         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
28004         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
28005         # OST0 is on ost1, OST1 is on ost2.
28006         # So this fail_val specifies OST0
28007         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
28008         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
28009
28010         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
28011                 error "parallel dio write with failure on first stripe succeeded"
28012         stack_trap "rm -f $DIR/$tfile"
28013         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
28014
28015         # Place data in file for read
28016         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
28017                 error "parallel dio write failed"
28018
28019         # Fail read on OST0, first stripe
28020         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28021         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
28022         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
28023                 error "parallel dio read with error on first stripe succeeded"
28024         rm -f $DIR/$tfile.2
28025         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
28026
28027         # Switch to testing on OST1, second stripe
28028         # Clear file contents, maintain striping
28029         echo > $DIR/$tfile
28030         # Set up failure on OST1, second stripe:
28031         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
28032         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
28033
28034         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
28035                 error "parallel dio write with failure on second stripe succeeded"
28036         stack_trap "rm -f $DIR/$tfile"
28037         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
28038
28039         # Place data in file for read
28040         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
28041                 error "parallel dio write failed"
28042
28043         # Fail read on OST1, second stripe
28044         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28045         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
28046         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
28047                 error "parallel dio read with error on second stripe succeeded"
28048         rm -f $DIR/$tfile.2
28049         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
28050 }
28051 run_test 398m "test RPC failures with parallel dio"
28052
28053 # Parallel submission of DIO should not cause problems for append, but it's
28054 # important to verify.
28055 test_398n() { #  LU-13798
28056         $LFS setstripe -C 2 -S 1M $DIR/$tfile
28057
28058         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
28059                 error "dd to create source file failed"
28060         stack_trap "rm -f $DIR/$tfile"
28061
28062         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
28063                 error "parallel dio write with failure on second stripe succeeded"
28064         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
28065         diff $DIR/$tfile $DIR/$tfile.1
28066         [[ $? == 0 ]] || error "data incorrect after append"
28067
28068 }
28069 run_test 398n "test append with parallel DIO"
28070
28071 test_398o() {
28072         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
28073 }
28074 run_test 398o "right kms with DIO"
28075
28076 test_398p()
28077 {
28078         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28079         which aiocp || skip_env "no aiocp installed"
28080
28081         local stripe_size=$((1024 * 1024)) #1 MiB
28082         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28083         local file_size=$((25 * stripe_size))
28084
28085         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28086         stack_trap "rm -f $DIR/$tfile*"
28087         # Just a bit bigger than the largest size in the test set below
28088         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28089                 error "buffered i/o to create file failed"
28090
28091         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28092                 $((stripe_size * 4)); do
28093
28094                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28095
28096                 echo "bs: $bs, file_size $file_size"
28097                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
28098                         $DIR/$tfile.1 $DIR/$tfile.2 &
28099                 pid_dio1=$!
28100                 # Buffered I/O with similar but not the same block size
28101                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28102                         conv=notrunc &
28103                 pid_bio2=$!
28104                 wait $pid_dio1
28105                 rc1=$?
28106                 wait $pid_bio2
28107                 rc2=$?
28108                 if (( rc1 != 0 )); then
28109                         error "aio copy 1 w/bsize $bs failed: $rc1"
28110                 fi
28111                 if (( rc2 != 0 )); then
28112                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28113                 fi
28114
28115                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28116                         error "size incorrect"
28117                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
28118                         error "files differ, bsize $bs"
28119                 rm -f $DIR/$tfile.2
28120         done
28121 }
28122 run_test 398p "race aio with buffered i/o"
28123
28124 test_398q()
28125 {
28126         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28127
28128         local stripe_size=$((1024 * 1024)) #1 MiB
28129         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28130         local file_size=$((25 * stripe_size))
28131
28132         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28133         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28134
28135         # Just a bit bigger than the largest size in the test set below
28136         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28137                 error "buffered i/o to create file failed"
28138
28139         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28140                 $((stripe_size * 4)); do
28141
28142                 echo "bs: $bs, file_size $file_size"
28143                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
28144                         conv=notrunc oflag=direct iflag=direct &
28145                 pid_dio1=$!
28146                 # Buffered I/O with similar but not the same block size
28147                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28148                         conv=notrunc &
28149                 pid_bio2=$!
28150                 wait $pid_dio1
28151                 rc1=$?
28152                 wait $pid_bio2
28153                 rc2=$?
28154                 if (( rc1 != 0 )); then
28155                         error "dio copy 1 w/bsize $bs failed: $rc1"
28156                 fi
28157                 if (( rc2 != 0 )); then
28158                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28159                 fi
28160
28161                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28162                         error "size incorrect"
28163                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28164                         error "files differ, bsize $bs"
28165         done
28166
28167         rm -f $DIR/$tfile*
28168 }
28169 run_test 398q "race dio with buffered i/o"
28170
28171 test_398r() {
28172         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28173         echo "hello, world" > $DIR/$tfile
28174
28175         cancel_lru_locks osc
28176
28177 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28178         do_facet ost1 $LCTL set_param fail_loc=0x20f
28179         cat $DIR/$tfile > /dev/null && error "cat should fail"
28180         return 0
28181 }
28182 run_test 398r "i/o error on file read"
28183
28184 test_398s() {
28185         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28186                 skip "remote OST"
28187
28188         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28189                 error "mirror create failed"
28190
28191         echo "hello, world" > $DIR/$tfile
28192         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28193
28194         cancel_lru_locks osc
28195
28196 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28197         do_facet ost1 $LCTL set_param fail_loc=0x20f
28198         cat $DIR/$tfile > /dev/null && error "cat should fail"
28199         return 0
28200 }
28201 run_test 398s "i/o error on mirror file read"
28202
28203 test_fake_rw() {
28204         local read_write=$1
28205         if [ "$read_write" = "write" ]; then
28206                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28207         elif [ "$read_write" = "read" ]; then
28208                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28209         else
28210                 error "argument error"
28211         fi
28212
28213         # turn off debug for performance testing
28214         local saved_debug=$($LCTL get_param -n debug)
28215         $LCTL set_param debug=0
28216
28217         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28218
28219         # get ost1 size - $FSNAME-OST0000
28220         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28221         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28222         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28223
28224         if [ "$read_write" = "read" ]; then
28225                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28226         fi
28227
28228         local start_time=$(date +%s.%N)
28229         $dd_cmd bs=1M count=$blocks oflag=sync ||
28230                 error "real dd $read_write error"
28231         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28232
28233         if [ "$read_write" = "write" ]; then
28234                 rm -f $DIR/$tfile
28235         fi
28236
28237         # define OBD_FAIL_OST_FAKE_RW           0x238
28238         do_facet ost1 $LCTL set_param fail_loc=0x238
28239
28240         local start_time=$(date +%s.%N)
28241         $dd_cmd bs=1M count=$blocks oflag=sync ||
28242                 error "fake dd $read_write error"
28243         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28244
28245         if [ "$read_write" = "write" ]; then
28246                 # verify file size
28247                 cancel_lru_locks osc
28248                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28249                         error "$tfile size not $blocks MB"
28250         fi
28251         do_facet ost1 $LCTL set_param fail_loc=0
28252
28253         echo "fake $read_write $duration_fake vs. normal $read_write" \
28254                 "$duration in seconds"
28255         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28256                 error_not_in_vm "fake write is slower"
28257
28258         $LCTL set_param -n debug="$saved_debug"
28259         rm -f $DIR/$tfile
28260 }
28261 test_399a() { # LU-7655 for OST fake write
28262         remote_ost_nodsh && skip "remote OST with nodsh"
28263
28264         test_fake_rw write
28265 }
28266 run_test 399a "fake write should not be slower than normal write"
28267
28268 test_399b() { # LU-8726 for OST fake read
28269         remote_ost_nodsh && skip "remote OST with nodsh"
28270         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28271                 skip_env "ldiskfs only test"
28272         fi
28273
28274         test_fake_rw read
28275 }
28276 run_test 399b "fake read should not be slower than normal read"
28277
28278 test_400a() { # LU-1606, was conf-sanity test_74
28279         if ! which $CC > /dev/null 2>&1; then
28280                 skip_env "$CC is not installed"
28281         fi
28282
28283         local extra_flags=''
28284         local out=$TMP/$tfile
28285         local prefix=/usr/include/lustre
28286         local prog
28287
28288         # Oleg removes .c files in his test rig so test if any c files exist
28289         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28290                 skip_env "Needed .c test files are missing"
28291
28292         if ! [[ -d $prefix ]]; then
28293                 # Assume we're running in tree and fixup the include path.
28294                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28295                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28296                 extra_flags+=" -L$LUSTRE/utils/.libs"
28297         fi
28298
28299         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28300                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28301                         error "client api broken"
28302         done
28303         rm -f $out
28304 }
28305 run_test 400a "Lustre client api program can compile and link"
28306
28307 test_400b() { # LU-1606, LU-5011
28308         local header
28309         local out=$TMP/$tfile
28310         local prefix=/usr/include/linux/lustre
28311
28312         # We use a hard coded prefix so that this test will not fail
28313         # when run in tree. There are headers in lustre/include/lustre/
28314         # that are not packaged (like lustre_idl.h) and have more
28315         # complicated include dependencies (like config.h and lnet/types.h).
28316         # Since this test about correct packaging we just skip them when
28317         # they don't exist (see below) rather than try to fixup cppflags.
28318
28319         if ! which $CC > /dev/null 2>&1; then
28320                 skip_env "$CC is not installed"
28321         fi
28322
28323         for header in $prefix/*.h; do
28324                 if ! [[ -f "$header" ]]; then
28325                         continue
28326                 fi
28327
28328                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28329                         continue # lustre_ioctl.h is internal header
28330                 fi
28331
28332                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28333                         error "cannot compile '$header'"
28334         done
28335         rm -f $out
28336 }
28337 run_test 400b "packaged headers can be compiled"
28338
28339 test_401a() { #LU-7437
28340         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28341         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28342
28343         #count the number of parameters by "list_param -R"
28344         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28345         #count the number of parameters by listing proc files
28346         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28347         echo "proc_dirs='$proc_dirs'"
28348         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28349         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28350                       sort -u | wc -l)
28351
28352         [ $params -eq $procs ] ||
28353                 error "found $params parameters vs. $procs proc files"
28354
28355         # test the list_param -D option only returns directories
28356         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28357         #count the number of parameters by listing proc directories
28358         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28359                 sort -u | wc -l)
28360
28361         [ $params -eq $procs ] ||
28362                 error "found $params parameters vs. $procs proc files"
28363 }
28364 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28365
28366 test_401b() {
28367         # jobid_var may not allow arbitrary values, so use jobid_name
28368         # if available
28369         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28370                 local testname=jobid_name tmp='testing%p'
28371         else
28372                 local testname=jobid_var tmp=testing
28373         fi
28374
28375         local save=$($LCTL get_param -n $testname)
28376
28377         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28378                 error "no error returned when setting bad parameters"
28379
28380         local jobid_new=$($LCTL get_param -n foe $testname baz)
28381         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28382
28383         $LCTL set_param -n fog=bam $testname=$save bat=fog
28384         local jobid_old=$($LCTL get_param -n foe $testname bag)
28385         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28386 }
28387 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28388
28389 test_401c() {
28390         # jobid_var may not allow arbitrary values, so use jobid_name
28391         # if available
28392         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28393                 local testname=jobid_name
28394         else
28395                 local testname=jobid_var
28396         fi
28397
28398         local jobid_var_old=$($LCTL get_param -n $testname)
28399         local jobid_var_new
28400
28401         $LCTL set_param $testname= &&
28402                 error "no error returned for 'set_param a='"
28403
28404         jobid_var_new=$($LCTL get_param -n $testname)
28405         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28406                 error "$testname was changed by setting without value"
28407
28408         $LCTL set_param $testname &&
28409                 error "no error returned for 'set_param a'"
28410
28411         jobid_var_new=$($LCTL get_param -n $testname)
28412         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28413                 error "$testname was changed by setting without value"
28414 }
28415 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28416
28417 test_401d() {
28418         # jobid_var may not allow arbitrary values, so use jobid_name
28419         # if available
28420         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28421                 local testname=jobid_name new_value='foo=bar%p'
28422         else
28423                 local testname=jobid_var new_valuie=foo=bar
28424         fi
28425
28426         local jobid_var_old=$($LCTL get_param -n $testname)
28427         local jobid_var_new
28428
28429         $LCTL set_param $testname=$new_value ||
28430                 error "'set_param a=b' did not accept a value containing '='"
28431
28432         jobid_var_new=$($LCTL get_param -n $testname)
28433         [[ "$jobid_var_new" == "$new_value" ]] ||
28434                 error "'set_param a=b' failed on a value containing '='"
28435
28436         # Reset the $testname to test the other format
28437         $LCTL set_param $testname=$jobid_var_old
28438         jobid_var_new=$($LCTL get_param -n $testname)
28439         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28440                 error "failed to reset $testname"
28441
28442         $LCTL set_param $testname $new_value ||
28443                 error "'set_param a b' did not accept a value containing '='"
28444
28445         jobid_var_new=$($LCTL get_param -n $testname)
28446         [[ "$jobid_var_new" == "$new_value" ]] ||
28447                 error "'set_param a b' failed on a value containing '='"
28448
28449         $LCTL set_param $testname $jobid_var_old
28450         jobid_var_new=$($LCTL get_param -n $testname)
28451         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28452                 error "failed to reset $testname"
28453 }
28454 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28455
28456 test_401e() { # LU-14779
28457         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28458                 error "lctl list_param MGC* failed"
28459         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28460         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28461                 error "lctl get_param lru_size failed"
28462 }
28463 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28464
28465 test_402() {
28466         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28467         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28468                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28469         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28470                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28471                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28472         remote_mds_nodsh && skip "remote MDS with nodsh"
28473
28474         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28475 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28476         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28477         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28478                 echo "Touch failed - OK"
28479 }
28480 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28481
28482 test_403() {
28483         local file1=$DIR/$tfile.1
28484         local file2=$DIR/$tfile.2
28485         local tfile=$TMP/$tfile
28486
28487         rm -f $file1 $file2 $tfile
28488
28489         touch $file1
28490         ln $file1 $file2
28491
28492         # 30 sec OBD_TIMEOUT in ll_getattr()
28493         # right before populating st_nlink
28494         $LCTL set_param fail_loc=0x80001409
28495         stat -c %h $file1 > $tfile &
28496
28497         # create an alias, drop all locks and reclaim the dentry
28498         < $file2
28499         cancel_lru_locks mdc
28500         cancel_lru_locks osc
28501         sysctl -w vm.drop_caches=2
28502
28503         wait
28504
28505         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28506
28507         rm -f $tfile $file1 $file2
28508 }
28509 run_test 403 "i_nlink should not drop to zero due to aliasing"
28510
28511 test_404() { # LU-6601
28512         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28513                 skip "Need server version newer than 2.8.52"
28514         remote_mds_nodsh && skip "remote MDS with nodsh"
28515
28516         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28517                 awk '/osp .*-osc-MDT/ { print $4}')
28518
28519         local osp
28520         for osp in $mosps; do
28521                 echo "Deactivate: " $osp
28522                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28523                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28524                         awk -vp=$osp '$4 == p { print $2 }')
28525                 [ $stat = IN ] || {
28526                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28527                         error "deactivate error"
28528                 }
28529                 echo "Activate: " $osp
28530                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28531                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28532                         awk -vp=$osp '$4 == p { print $2 }')
28533                 [ $stat = UP ] || {
28534                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28535                         error "activate error"
28536                 }
28537         done
28538 }
28539 run_test 404 "validate manual {de}activated works properly for OSPs"
28540
28541 test_405() {
28542         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28543         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28544                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28545                         skip "Layout swap lock is not supported"
28546
28547         check_swap_layouts_support
28548         check_swap_layout_no_dom $DIR
28549
28550         test_mkdir $DIR/$tdir
28551         swap_lock_test -d $DIR/$tdir ||
28552                 error "One layout swap locked test failed"
28553 }
28554 run_test 405 "Various layout swap lock tests"
28555
28556 test_406() {
28557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28558         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28559         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28561         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28562                 skip "Need MDS version at least 2.8.50"
28563
28564         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28565         local test_pool=$TESTNAME
28566
28567         pool_add $test_pool || error "pool_add failed"
28568         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28569                 error "pool_add_targets failed"
28570
28571         save_layout_restore_at_exit $MOUNT
28572
28573         # parent set default stripe count only, child will stripe from both
28574         # parent and fs default
28575         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28576                 error "setstripe $MOUNT failed"
28577         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28578         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28579         for i in $(seq 10); do
28580                 local f=$DIR/$tdir/$tfile.$i
28581                 touch $f || error "touch failed"
28582                 local count=$($LFS getstripe -c $f)
28583                 [ $count -eq $OSTCOUNT ] ||
28584                         error "$f stripe count $count != $OSTCOUNT"
28585                 local offset=$($LFS getstripe -i $f)
28586                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28587                 local size=$($LFS getstripe -S $f)
28588                 [ $size -eq $((def_stripe_size * 2)) ] ||
28589                         error "$f stripe size $size != $((def_stripe_size * 2))"
28590                 local pool=$($LFS getstripe -p $f)
28591                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28592         done
28593
28594         # change fs default striping, delete parent default striping, now child
28595         # will stripe from new fs default striping only
28596         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28597                 error "change $MOUNT default stripe failed"
28598         $LFS setstripe -c 0 $DIR/$tdir ||
28599                 error "delete $tdir default stripe failed"
28600         for i in $(seq 11 20); do
28601                 local f=$DIR/$tdir/$tfile.$i
28602                 touch $f || error "touch $f failed"
28603                 local count=$($LFS getstripe -c $f)
28604                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28605                 local offset=$($LFS getstripe -i $f)
28606                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28607                 local size=$($LFS getstripe -S $f)
28608                 [ $size -eq $def_stripe_size ] ||
28609                         error "$f stripe size $size != $def_stripe_size"
28610                 local pool=$($LFS getstripe -p $f)
28611                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28612         done
28613
28614         unlinkmany $DIR/$tdir/$tfile. 1 20
28615
28616         local f=$DIR/$tdir/$tfile
28617         pool_remove_all_targets $test_pool $f
28618         pool_remove $test_pool $f
28619 }
28620 run_test 406 "DNE support fs default striping"
28621
28622 test_407() {
28623         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28624         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28625                 skip "Need MDS version at least 2.8.55"
28626         remote_mds_nodsh && skip "remote MDS with nodsh"
28627
28628         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28629                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28630         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28631                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28632         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28633
28634         #define OBD_FAIL_DT_TXN_STOP    0x2019
28635         for idx in $(seq $MDSCOUNT); do
28636                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28637         done
28638         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28639         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28640                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28641         true
28642 }
28643 run_test 407 "transaction fail should cause operation fail"
28644
28645 test_408() {
28646         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28647
28648         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28649         lctl set_param fail_loc=0x8000040a
28650         # let ll_prepare_partial_page() fail
28651         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28652
28653         rm -f $DIR/$tfile
28654
28655         # create at least 100 unused inodes so that
28656         # shrink_icache_memory(0) should not return 0
28657         touch $DIR/$tfile-{0..100}
28658         rm -f $DIR/$tfile-{0..100}
28659         sync
28660
28661         echo 2 > /proc/sys/vm/drop_caches
28662 }
28663 run_test 408 "drop_caches should not hang due to page leaks"
28664
28665 test_409()
28666 {
28667         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28668
28669         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28670         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28671         touch $DIR/$tdir/guard || error "(2) Fail to create"
28672
28673         local PREFIX=$(str_repeat 'A' 128)
28674         echo "Create 1K hard links start at $(date)"
28675         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28676                 error "(3) Fail to hard link"
28677
28678         echo "Links count should be right although linkEA overflow"
28679         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28680         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28681         [ $linkcount -eq 1001 ] ||
28682                 error "(5) Unexpected hard links count: $linkcount"
28683
28684         echo "List all links start at $(date)"
28685         ls -l $DIR/$tdir/foo > /dev/null ||
28686                 error "(6) Fail to list $DIR/$tdir/foo"
28687
28688         echo "Unlink hard links start at $(date)"
28689         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28690                 error "(7) Fail to unlink"
28691         echo "Unlink hard links finished at $(date)"
28692 }
28693 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28694
28695 test_410()
28696 {
28697         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28698                 skip "Need client version at least 2.9.59"
28699
28700         # Create a file, and stat it from the kernel
28701         local testfile=$DIR/$tfile
28702         touch $testfile
28703
28704         local run_id=$RANDOM
28705         local my_ino=$(stat --format "%i" $testfile)
28706
28707         # Try to insert the module.
28708         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28709                 error "load_module failed"
28710
28711         # Anything but success is a test failure
28712         dmesg | grep -q \
28713             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28714             error "no inode match"
28715
28716         # Remove the test module
28717         rmmod -v kinode ||
28718                 error "rmmod failed (may trigger a failure in a later test)"
28719 }
28720 run_test 410 "Test inode number returned from kernel thread"
28721
28722 cleanup_test411_cgroup() {
28723         trap 0
28724         cat $1/memory.stat
28725         rmdir "$1"
28726 }
28727
28728 test_411a() {
28729         local cg_basedir=/sys/fs/cgroup/memory
28730         # LU-9966
28731         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28732                 skip "no setup for cgroup"
28733
28734         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28735                 error "test file creation failed"
28736         cancel_lru_locks osc
28737
28738         # Create a very small memory cgroup to force a slab allocation error
28739         local cgdir=$cg_basedir/osc_slab_alloc
28740         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28741         trap "cleanup_test411_cgroup $cgdir" EXIT
28742         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28743         echo 1M > $cgdir/memory.limit_in_bytes
28744
28745         # Should not LBUG, just be killed by oom-killer
28746         # dd will return 0 even allocation failure in some environment.
28747         # So don't check return value
28748         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28749         cleanup_test411_cgroup $cgdir
28750
28751         return 0
28752 }
28753 run_test 411a "Slab allocation error with cgroup does not LBUG"
28754
28755 test_411b() {
28756         local cg_basedir=/sys/fs/cgroup/memory
28757         # LU-9966
28758         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28759                 skip "no setup for cgroup"
28760         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28761         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28762         # limit, so we have 384M in cgroup
28763         # (arm) this seems to hit OOM more often than x86, so 1024M
28764         if [[ $(uname -m) = aarch64 ]]; then
28765                 local memlimit_mb=1024
28766         else
28767                 local memlimit_mb=384
28768         fi
28769
28770         # Create a cgroup and set memory limit
28771         # (tfile is used as an easy way to get a recognizable cgroup name)
28772         local cgdir=$cg_basedir/$tfile
28773         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28774         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28775         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28776
28777         echo "writing first file"
28778         # Write a file 4x the memory limit in size
28779         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28780                 error "(1) failed to write successfully"
28781
28782         sync
28783         cancel_lru_locks osc
28784
28785         rm -f $DIR/$tfile
28786         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28787
28788         # Try writing at a larger block size
28789         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28790         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28791         # need *some* memory to do IO in)
28792         echo "writing at larger block size"
28793         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28794                 error "(3) failed to write successfully"
28795
28796         sync
28797         cancel_lru_locks osc
28798         rm -f $DIR/$tfile
28799         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28800
28801         # Try writing multiple files at once
28802         echo "writing multiple files"
28803         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28804         local pid1=$!
28805         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28806         local pid2=$!
28807         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28808         local pid3=$!
28809         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28810         local pid4=$!
28811
28812         wait $pid1
28813         local rc1=$?
28814         wait $pid2
28815         local rc2=$?
28816         wait $pid3
28817         local rc3=$?
28818         wait $pid4
28819         local rc4=$?
28820         if (( rc1 != 0)); then
28821                 error "error $rc1 writing to file from $pid1"
28822         fi
28823         if (( rc2 != 0)); then
28824                 error "error $rc2 writing to file from $pid2"
28825         fi
28826         if (( rc3 != 0)); then
28827                 error "error $rc3 writing to file from $pid3"
28828         fi
28829         if (( rc4 != 0)); then
28830                 error "error $rc4 writing to file from $pid4"
28831         fi
28832
28833         sync
28834         cancel_lru_locks osc
28835
28836         # These files can be large-ish (~1 GiB total), so delete them rather
28837         # than leave for later cleanup
28838         rm -f $DIR/$tfile.*
28839         return 0
28840 }
28841 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28842
28843 test_412() {
28844         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28845         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28846                 skip "Need server version at least 2.10.55"
28847
28848         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28849                 error "mkdir failed"
28850         $LFS getdirstripe $DIR/$tdir
28851         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28852         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28853                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28854         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28855         [ $stripe_count -eq 2 ] ||
28856                 error "expect 2 get $stripe_count"
28857
28858         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28859
28860         local index
28861         local index2
28862
28863         # subdirs should be on the same MDT as parent
28864         for i in $(seq 0 $((MDSCOUNT - 1))); do
28865                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28866                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28867                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28868                 (( index == i )) || error "mdt$i/sub on MDT$index"
28869         done
28870
28871         # stripe offset -1, ditto
28872         for i in {1..10}; do
28873                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28874                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28875                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28876                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28877                 (( index == index2 )) ||
28878                         error "qos$i on MDT$index, sub on MDT$index2"
28879         done
28880
28881         local testdir=$DIR/$tdir/inherit
28882
28883         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28884         # inherit 2 levels
28885         for i in 1 2; do
28886                 testdir=$testdir/s$i
28887                 mkdir $testdir || error "mkdir $testdir failed"
28888                 index=$($LFS getstripe -m $testdir)
28889                 (( index == 1 )) ||
28890                         error "$testdir on MDT$index"
28891         done
28892
28893         # not inherit any more
28894         testdir=$testdir/s3
28895         mkdir $testdir || error "mkdir $testdir failed"
28896         getfattr -d -m dmv $testdir | grep dmv &&
28897                 error "default LMV set on $testdir" || true
28898 }
28899 run_test 412 "mkdir on specific MDTs"
28900
28901 TEST413_COUNT=${TEST413_COUNT:-200}
28902
28903 #
28904 # set_maxage() is used by test_413 only.
28905 # This is a helper function to set maxage. Does not return any value.
28906 # Input: maxage to set
28907 #
28908 set_maxage() {
28909         local lmv_qos_maxage
28910         local lod_qos_maxage
28911         local new_maxage=$1
28912
28913         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28914         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28915         stack_trap "$LCTL set_param \
28916                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28917         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28918                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28919         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28920                 lod.*.mdt_qos_maxage=$new_maxage
28921         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28922                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28923 }
28924
28925 generate_uneven_mdts() {
28926         local threshold=$1
28927         local ffree
28928         local bavail
28929         local max
28930         local min
28931         local max_index
28932         local min_index
28933         local tmp
28934         local i
28935
28936         echo
28937         echo "Check for uneven MDTs: "
28938
28939         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28940         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28941         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28942
28943         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28944         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28945         max_index=0
28946         min_index=0
28947         for ((i = 1; i < ${#ffree[@]}; i++)); do
28948                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28949                 if [ $tmp -gt $max ]; then
28950                         max=$tmp
28951                         max_index=$i
28952                 fi
28953                 if [ $tmp -lt $min ]; then
28954                         min=$tmp
28955                         min_index=$i
28956                 fi
28957         done
28958
28959         (( min > 0 )) || skip "low space on MDT$min_index"
28960         (( ${ffree[min_index]} > 0 )) ||
28961                 skip "no free files on MDT$min_index"
28962         (( ${ffree[min_index]} < 10000000 )) ||
28963                 skip "too many free files on MDT$min_index"
28964
28965         # Check if we need to generate uneven MDTs
28966         local diff=$(((max - min) * 100 / min))
28967         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28968         local testdir # individual folder within $testdirp
28969         local start
28970         local cmd
28971
28972         # fallocate is faster to consume space on MDT, if available
28973         if check_fallocate_supported mds$((min_index + 1)); then
28974                 cmd="fallocate -l 128K "
28975         else
28976                 cmd="dd if=/dev/zero bs=128K count=1 of="
28977         fi
28978
28979         echo "using cmd $cmd"
28980         for (( i = 0; diff < threshold; i++ )); do
28981                 testdir=${testdirp}/$i
28982                 [ -d $testdir ] && continue
28983
28984                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28985
28986                 mkdir -p $testdirp
28987                 # generate uneven MDTs, create till $threshold% diff
28988                 echo -n "weight diff=$diff% must be > $threshold% ..."
28989                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28990                 $LFS mkdir -i $min_index $testdir ||
28991                         error "mkdir $testdir failed"
28992                 $LFS setstripe -E 1M -L mdt $testdir ||
28993                         error "setstripe $testdir failed"
28994                 start=$SECONDS
28995                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28996                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28997                 done
28998                 sync; sleep 1; sync
28999
29000                 # wait for QOS to update
29001                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
29002
29003                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
29004                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
29005                 max=$(((${ffree[max_index]} >> 8) *
29006                         (${bavail[max_index]} * bsize >> 16)))
29007                 min=$(((${ffree[min_index]} >> 8) *
29008                         (${bavail[min_index]} * bsize >> 16)))
29009                 (( min > 0 )) || skip "low space on MDT$min_index"
29010                 diff=$(((max - min) * 100 / min))
29011         done
29012
29013         echo "MDT filesfree available: ${ffree[*]}"
29014         echo "MDT blocks available: ${bavail[*]}"
29015         echo "weight diff=$diff%"
29016 }
29017
29018 test_qos_mkdir() {
29019         local mkdir_cmd=$1
29020         local stripe_count=$2
29021         local mdts=$(comma_list $(mdts_nodes))
29022
29023         local testdir
29024         local lmv_qos_prio_free
29025         local lmv_qos_threshold_rr
29026         local lod_qos_prio_free
29027         local lod_qos_threshold_rr
29028         local total
29029         local count
29030         local i
29031
29032         # @total is total directories created if it's testing plain
29033         # directories, otherwise it's total stripe object count for
29034         # striped directories test.
29035         # remote/striped directory unlinking is slow on zfs and may
29036         # timeout, test with fewer directories
29037         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
29038
29039         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
29040         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
29041         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29042                 head -n1)
29043         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
29044         stack_trap "$LCTL set_param \
29045                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
29046         stack_trap "$LCTL set_param \
29047                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
29048
29049         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
29050                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
29051         lod_qos_prio_free=${lod_qos_prio_free%%%}
29052         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
29053                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
29054         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
29055         stack_trap "do_nodes $mdts $LCTL set_param \
29056                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
29057         stack_trap "do_nodes $mdts $LCTL set_param \
29058                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
29059
29060         # decrease statfs age, so that it can be updated in time
29061         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
29062         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
29063
29064         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29065         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
29066
29067         testdir=$DIR/$tdir-s$stripe_count/rr
29068
29069         local stripe_index=$($LFS getstripe -m $testdir)
29070         local test_mkdir_rr=true
29071
29072         getfattr -d -m dmv -e hex $testdir | grep dmv
29073         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
29074                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
29075                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
29076                         test_mkdir_rr=false
29077         fi
29078
29079         echo
29080         $test_mkdir_rr &&
29081                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
29082                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
29083
29084         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29085         for (( i = 0; i < total / stripe_count; i++ )); do
29086                 eval $mkdir_cmd $testdir/subdir$i ||
29087                         error "$mkdir_cmd subdir$i failed"
29088         done
29089
29090         for (( i = 0; i < $MDSCOUNT; i++ )); do
29091                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29092                 echo "$count directories created on MDT$i"
29093                 if $test_mkdir_rr; then
29094                         (( count == total / stripe_count / MDSCOUNT )) ||
29095                                 error "subdirs are not evenly distributed"
29096                 elif (( i == stripe_index )); then
29097                         (( count == total / stripe_count )) ||
29098                                 error "$count subdirs created on MDT$i"
29099                 else
29100                         (( count == 0 )) ||
29101                                 error "$count subdirs created on MDT$i"
29102                 fi
29103
29104                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
29105                         count=$($LFS getdirstripe $testdir/* |
29106                                 grep -c -P "^\s+$i\t")
29107                         echo "$count stripes created on MDT$i"
29108                         # deviation should < 5% of average
29109                         delta=$((count - total / MDSCOUNT))
29110                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
29111                                 error "stripes are not evenly distributed"
29112                 fi
29113         done
29114
29115         echo
29116         echo "Check for uneven MDTs: "
29117
29118         local ffree
29119         local bavail
29120         local max
29121         local min
29122         local max_index
29123         local min_index
29124         local tmp
29125
29126         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29127         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29128         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29129
29130         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29131         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29132         max_index=0
29133         min_index=0
29134         for ((i = 1; i < ${#ffree[@]}; i++)); do
29135                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29136                 if [ $tmp -gt $max ]; then
29137                         max=$tmp
29138                         max_index=$i
29139                 fi
29140                 if [ $tmp -lt $min ]; then
29141                         min=$tmp
29142                         min_index=$i
29143                 fi
29144         done
29145         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29146
29147         (( min > 0 )) || skip "low space on MDT$min_index"
29148         (( ${ffree[min_index]} < 10000000 )) ||
29149                 skip "too many free files on MDT$min_index"
29150
29151         generate_uneven_mdts 120
29152
29153         echo "MDT filesfree available: ${ffree[*]}"
29154         echo "MDT blocks available: ${bavail[*]}"
29155         echo "weight diff=$(((max - min) * 100 / min))%"
29156         echo
29157         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29158
29159         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29160         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29161         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29162         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29163
29164         sleep 1
29165
29166         testdir=$DIR/$tdir-s$stripe_count/qos
29167
29168         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29169         for (( i = 0; i < total / stripe_count; i++ )); do
29170                 eval $mkdir_cmd $testdir/subdir$i ||
29171                         error "$mkdir_cmd subdir$i failed"
29172         done
29173
29174         max=0
29175         for (( i = 0; i < $MDSCOUNT; i++ )); do
29176                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29177                 (( count > max )) && max=$count
29178                 echo "$count directories created on MDT$i : curmax=$max"
29179         done
29180
29181         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29182
29183         # D-value should > 10% of average
29184         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29185                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29186
29187         # ditto for stripes
29188         if (( stripe_count > 1 )); then
29189                 max=0
29190                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29191                         count=$($LFS getdirstripe $testdir/* |
29192                                 grep -c -P "^\s+$i\t")
29193                         (( count > max )) && max=$count
29194                         echo "$count stripes created on MDT$i"
29195                 done
29196
29197                 min=$($LFS getdirstripe $testdir/* |
29198                         grep -c -P "^\s+$min_index\t")
29199                 (( max - min > total / MDSCOUNT / 10 )) ||
29200                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29201         fi
29202 }
29203
29204 most_full_mdt() {
29205         local ffree
29206         local bavail
29207         local bsize
29208         local min
29209         local min_index
29210         local tmp
29211
29212         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29213         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29214         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29215
29216         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29217         min_index=0
29218         for ((i = 1; i < ${#ffree[@]}; i++)); do
29219                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29220                 (( tmp < min )) && min=$tmp && min_index=$i
29221         done
29222
29223         echo -n $min_index
29224 }
29225
29226 test_413a() {
29227         [ $MDSCOUNT -lt 2 ] &&
29228                 skip "We need at least 2 MDTs for this test"
29229
29230         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29231                 skip "Need server version at least 2.12.52"
29232
29233         local stripe_max=$((MDSCOUNT - 1))
29234         local stripe_count
29235
29236         # let caller set maxage for latest result
29237         set_maxage 1
29238
29239         # fill MDT unevenly
29240         generate_uneven_mdts 120
29241
29242         # test 4-stripe directory at most, otherwise it's too slow
29243         # We are being very defensive. Although Autotest uses 4 MDTs.
29244         # We make sure stripe_max does not go over 4.
29245         (( stripe_max > 4 )) && stripe_max=4
29246         # unlinking striped directory is slow on zfs, and may timeout, only test
29247         # plain directory
29248         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29249         for stripe_count in $(seq 1 $stripe_max); do
29250                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29251                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29252                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29253                         error "mkdir failed"
29254                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29255         done
29256 }
29257 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29258
29259 test_413b() {
29260         [ $MDSCOUNT -lt 2 ] &&
29261                 skip "We need at least 2 MDTs for this test"
29262
29263         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29264                 skip "Need server version at least 2.12.52"
29265
29266         local stripe_max=$((MDSCOUNT - 1))
29267         local testdir
29268         local stripe_count
29269
29270         # let caller set maxage for latest result
29271         set_maxage 1
29272
29273         # fill MDT unevenly
29274         generate_uneven_mdts 120
29275
29276         # test 4-stripe directory at most, otherwise it's too slow
29277         # We are being very defensive. Although Autotest uses 4 MDTs.
29278         # We make sure stripe_max does not go over 4.
29279         (( stripe_max > 4 )) && stripe_max=4
29280         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29281         for stripe_count in $(seq 1 $stripe_max); do
29282                 testdir=$DIR/$tdir-s$stripe_count
29283                 mkdir $testdir || error "mkdir $testdir failed"
29284                 mkdir $testdir/rr || error "mkdir rr failed"
29285                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29286                         error "mkdir qos failed"
29287                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29288                         $testdir/rr || error "setdirstripe rr failed"
29289                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29290                         error "setdirstripe failed"
29291                 test_qos_mkdir "mkdir" $stripe_count
29292         done
29293 }
29294 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29295
29296 test_413c() {
29297         (( $MDSCOUNT >= 2 )) ||
29298                 skip "We need at least 2 MDTs for this test"
29299
29300         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29301                 skip "Need server version at least 2.14.51"
29302
29303         local testdir
29304         local inherit
29305         local inherit_rr
29306         local lmv_qos_maxage
29307         local lod_qos_maxage
29308
29309         # let caller set maxage for latest result
29310         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29311         $LCTL set_param lmv.*.qos_maxage=1
29312         stack_trap "$LCTL set_param \
29313                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29314         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29315                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29316         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29317                 lod.*.mdt_qos_maxage=1
29318         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29319                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29320
29321         # fill MDT unevenly
29322         generate_uneven_mdts 120
29323
29324         testdir=$DIR/${tdir}-s1
29325         mkdir $testdir || error "mkdir $testdir failed"
29326         mkdir $testdir/rr || error "mkdir rr failed"
29327         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29328         # default max_inherit is -1, default max_inherit_rr is 0
29329         $LFS setdirstripe -D -c 1 $testdir/rr ||
29330                 error "setdirstripe rr failed"
29331         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29332                 error "setdirstripe qos failed"
29333         test_qos_mkdir "mkdir" 1
29334
29335         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29336         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29337         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29338         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29339         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29340
29341         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29342         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29343         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29344         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29345         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29346         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29347         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29348                 error "level2 shouldn't have default LMV" || true
29349 }
29350 run_test 413c "mkdir with default LMV max inherit rr"
29351
29352 test_413d() {
29353         (( MDSCOUNT >= 2 )) ||
29354                 skip "We need at least 2 MDTs for this test"
29355
29356         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29357                 skip "Need server version at least 2.14.51"
29358
29359         local lmv_qos_threshold_rr
29360
29361         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29362                 head -n1)
29363         stack_trap "$LCTL set_param \
29364                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29365
29366         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29367         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29368         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29369                 error "$tdir shouldn't have default LMV"
29370         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29371                 error "mkdir sub failed"
29372
29373         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29374
29375         (( count == 100 )) || error "$count subdirs on MDT0"
29376 }
29377 run_test 413d "inherit ROOT default LMV"
29378
29379 test_413e() {
29380         (( MDSCOUNT >= 2 )) ||
29381                 skip "We need at least 2 MDTs for this test"
29382         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29383                 skip "Need server version at least 2.14.55"
29384
29385         local testdir=$DIR/$tdir
29386         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29387         local max_inherit
29388         local sub_max_inherit
29389
29390         mkdir -p $testdir || error "failed to create $testdir"
29391
29392         # set default max-inherit to -1 if stripe count is 0 or 1
29393         $LFS setdirstripe -D -c 1 $testdir ||
29394                 error "failed to set default LMV"
29395         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29396         (( max_inherit == -1 )) ||
29397                 error "wrong max_inherit value $max_inherit"
29398
29399         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29400         $LFS setdirstripe -D -c -1 $testdir ||
29401                 error "failed to set default LMV"
29402         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29403         (( max_inherit > 0 )) ||
29404                 error "wrong max_inherit value $max_inherit"
29405
29406         # and the subdir will decrease the max_inherit by 1
29407         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29408         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29409         (( sub_max_inherit == max_inherit - 1)) ||
29410                 error "wrong max-inherit of subdir $sub_max_inherit"
29411
29412         # check specified --max-inherit and warning message
29413         stack_trap "rm -f $tmpfile"
29414         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29415                 error "failed to set default LMV"
29416         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29417         (( max_inherit == -1 )) ||
29418                 error "wrong max_inherit value $max_inherit"
29419
29420         # check the warning messages
29421         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29422                 error "failed to detect warning string"
29423         fi
29424 }
29425 run_test 413e "check default max-inherit value"
29426
29427 test_fs_dmv_inherit()
29428 {
29429         local testdir=$DIR/$tdir
29430
29431         local count
29432         local inherit
29433         local inherit_rr
29434
29435         for i in 1 2; do
29436                 mkdir $testdir || error "mkdir $testdir failed"
29437                 count=$($LFS getdirstripe -D -c $testdir)
29438                 (( count == 1 )) ||
29439                         error "$testdir default LMV count mismatch $count != 1"
29440                 inherit=$($LFS getdirstripe -D -X $testdir)
29441                 (( inherit == 3 - i )) ||
29442                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29443                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29444                 (( inherit_rr == 3 - i )) ||
29445                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29446                 testdir=$testdir/sub
29447         done
29448
29449         mkdir $testdir || error "mkdir $testdir failed"
29450         count=$($LFS getdirstripe -D -c $testdir)
29451         (( count == 0 )) ||
29452                 error "$testdir default LMV count not zero: $count"
29453 }
29454
29455 test_413f() {
29456         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29457
29458         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29459                 skip "Need server version at least 2.14.55"
29460
29461         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29462                 error "dump $DIR default LMV failed"
29463         stack_trap "setfattr --restore=$TMP/dmv.ea"
29464
29465         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29466                 error "set $DIR default LMV failed"
29467
29468         test_fs_dmv_inherit
29469 }
29470 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29471
29472 test_413g() {
29473         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29474
29475         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29476         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29477                 error "dump $DIR default LMV failed"
29478         stack_trap "setfattr --restore=$TMP/dmv.ea"
29479
29480         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29481                 error "set $DIR default LMV failed"
29482
29483         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29484                 error "mount $MOUNT2 failed"
29485         stack_trap "umount_client $MOUNT2"
29486
29487         local saved_DIR=$DIR
29488
29489         export DIR=$MOUNT2
29490
29491         stack_trap "export DIR=$saved_DIR"
29492
29493         # first check filesystem-wide default LMV inheritance
29494         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29495
29496         # then check subdirs are spread to all MDTs
29497         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29498
29499         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29500
29501         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29502 }
29503 run_test 413g "enforce ROOT default LMV on subdir mount"
29504
29505 test_413h() {
29506         (( MDSCOUNT >= 2 )) ||
29507                 skip "We need at least 2 MDTs for this test"
29508
29509         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29510                 skip "Need server version at least 2.15.50.6"
29511
29512         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29513
29514         stack_trap "$LCTL set_param \
29515                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29516         $LCTL set_param lmv.*.qos_maxage=1
29517
29518         local depth=5
29519         local rr_depth=4
29520         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29521         local count=$((MDSCOUNT * 20))
29522
29523         generate_uneven_mdts 50
29524
29525         mkdir -p $dir || error "mkdir $dir failed"
29526         stack_trap "rm -rf $dir"
29527         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29528                 --max-inherit-rr=$rr_depth $dir
29529
29530         for ((d=0; d < depth + 2; d++)); do
29531                 log "dir=$dir:"
29532                 for ((sub=0; sub < count; sub++)); do
29533                         mkdir $dir/d$sub
29534                 done
29535                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29536                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29537                 # subdirs within $rr_depth should be created round-robin
29538                 if (( d < rr_depth )); then
29539                         (( ${num[0]} != count )) ||
29540                                 error "all objects created on MDT ${num[1]}"
29541                 fi
29542
29543                 dir=$dir/d0
29544         done
29545 }
29546 run_test 413h "don't stick to parent for round-robin dirs"
29547
29548 test_413i() {
29549         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29550
29551         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29552                 skip "Need server version at least 2.14.55"
29553
29554         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29555                 error "dump $DIR default LMV failed"
29556         stack_trap "setfattr --restore=$TMP/dmv.ea"
29557
29558         local testdir=$DIR/$tdir
29559         local def_max_rr=1
29560         local def_max=3
29561         local count
29562
29563         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29564                 --max-inherit-rr=$def_max_rr $DIR ||
29565                 error "set $DIR default LMV failed"
29566
29567         for i in $(seq 2 3); do
29568                 def_max=$((def_max - 1))
29569                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29570
29571                 mkdir $testdir
29572                 # RR is decremented and keeps zeroed once exhausted
29573                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29574                 (( count == def_max_rr )) ||
29575                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29576
29577                 # max-inherit is decremented
29578                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29579                 (( count == def_max )) ||
29580                         error_noexit "$testdir: max-inherit $count != $def_max"
29581
29582                 testdir=$testdir/d$i
29583         done
29584
29585         # d3 is the last inherited from ROOT, no inheritance anymore
29586         # i.e. no the default layout anymore
29587         mkdir -p $testdir/d4/d5
29588         count=$($LFS getdirstripe -D --max-inherit $testdir)
29589         (( count == -1 )) ||
29590                 error_noexit "$testdir: max-inherit $count != -1"
29591
29592         local p_count=$($LFS getdirstripe -i $testdir)
29593
29594         for i in $(seq 4 5); do
29595                 testdir=$testdir/d$i
29596
29597                 # the root default layout is not applied once exhausted
29598                 count=$($LFS getdirstripe -i $testdir)
29599                 (( count == p_count )) ||
29600                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29601         done
29602
29603         $LFS setdirstripe -i 0 $DIR/d2
29604         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29605         (( count == -1 )) ||
29606                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29607 }
29608 run_test 413i "check default layout inheritance"
29609
29610 test_413j()
29611 {
29612         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29613
29614         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29615         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29616                 error "setdirstripe $tdir failed"
29617
29618         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29619                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29620
29621         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29622         # setfattr dmv calls setdirstripe -D
29623         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29624                 error "setfattr sub failed"
29625         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29626                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29627
29628         [ $value == $value2 ] || error "dmv mismatch"
29629
29630         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29631
29632         # do not allow remove dmv by setfattr -x
29633         do_nodes $(comma_list $(mdts_nodes)) \
29634                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29635         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29636         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29637
29638         # allow remove dmv by setfattr -x
29639         do_nodes $(comma_list $(mdts_nodes)) \
29640                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29641         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29642         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29643         do_nodes $(comma_list $(mdts_nodes)) \
29644                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29645 }
29646 run_test 413j "set default LMV by setxattr"
29647
29648 test_413k() {
29649         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29650                 skip "Need server version at least 2.15.60"
29651
29652         local index1
29653         local index2
29654         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29655         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29656         local prefixes="abc:123:foo bar"
29657
29658         # add prefixes
29659         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29660         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29661
29662         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29663         index1=$($LFS getstripe -m $DIR/$tdir)
29664         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29665                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29666                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29667                 ((index1 == index2)) ||
29668                         error "$tdir on MDT$index1, $dname on MDT$index2"
29669         done
29670
29671         # remove prefixes
29672         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29673
29674         # total prefixes length > PAGE_SIZE can be printed correctly
29675         for c in {a..z}; do
29676                 prefixes=$(str_repeat $c 255)
29677                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29678         done
29679         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29680         ((count2 == count + 26)) ||
29681                 error "prefixes count $count2 != $((count + 26))"
29682 }
29683 run_test 413k "QoS mkdir exclude prefixes"
29684
29685 test_413z() {
29686         local pids=""
29687         local subdir
29688         local pid
29689
29690         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29691                 unlinkmany $subdir/f. $TEST413_COUNT &
29692                 pids="$pids $!"
29693         done
29694
29695         for pid in $pids; do
29696                 wait $pid
29697         done
29698
29699         true
29700 }
29701 run_test 413z "413 test cleanup"
29702
29703 test_414() {
29704 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29705         $LCTL set_param fail_loc=0x80000521
29706         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29707         rm -f $DIR/$tfile
29708         # This error path has sometimes left inflight requests dangling, so
29709         # test for this by remounting the client (umount will hang if there's
29710         # a dangling request)
29711         umount_client $MOUNT
29712         mount_client $MOUNT
29713 }
29714 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29715
29716 test_415() {
29717         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29718         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29719                 skip "Need server version at least 2.11.52"
29720
29721         # LU-11102
29722         local total=500
29723         local max=120
29724
29725         # this test may be slow on ZFS
29726         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29727
29728         # though this test is designed for striped directory, let's test normal
29729         # directory too since lock is always saved as CoS lock.
29730         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29731         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29732         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29733         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29734         wait_delete_completed_mds
29735
29736         # run a loop without concurrent touch to measure rename duration.
29737         # only for test debug/robustness, NOT part of COS functional test.
29738         local start_time=$SECONDS
29739         for ((i = 0; i < total; i++)); do
29740                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29741                         > /dev/null
29742         done
29743         local baseline=$((SECONDS - start_time))
29744         echo "rename $total files without 'touch' took $baseline sec"
29745
29746         (
29747                 while true; do
29748                         touch $DIR/$tdir
29749                 done
29750         ) &
29751         local setattr_pid=$!
29752
29753         # rename files back to original name so unlinkmany works
29754         start_time=$SECONDS
29755         for ((i = 0; i < total; i++)); do
29756                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29757                         > /dev/null
29758         done
29759         local duration=$((SECONDS - start_time))
29760
29761         kill -9 $setattr_pid
29762
29763         echo "rename $total files with 'touch' took $duration sec"
29764         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29765         (( duration <= max )) ||
29766                 error_not_in_vm "rename took $duration > $max sec"
29767 }
29768 run_test 415 "lock revoke is not missing"
29769
29770 test_416() {
29771         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29772                 skip "Need server version at least 2.11.55"
29773
29774         # define OBD_FAIL_OSD_TXN_START    0x19a
29775         do_facet mds1 lctl set_param fail_loc=0x19a
29776
29777         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29778
29779         true
29780 }
29781 run_test 416 "transaction start failure won't cause system hung"
29782
29783 cleanup_417() {
29784         trap 0
29785         do_nodes $(comma_list $(mdts_nodes)) \
29786                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29787         do_nodes $(comma_list $(mdts_nodes)) \
29788                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29789         do_nodes $(comma_list $(mdts_nodes)) \
29790                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29791 }
29792
29793 test_417() {
29794         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29795         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29796                 skip "Need MDS version at least 2.11.56"
29797
29798         trap cleanup_417 RETURN EXIT
29799
29800         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29801         do_nodes $(comma_list $(mdts_nodes)) \
29802                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29803         $LFS migrate -m 0 $DIR/$tdir.1 &&
29804                 error "migrate dir $tdir.1 should fail"
29805
29806         do_nodes $(comma_list $(mdts_nodes)) \
29807                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29808         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29809                 error "create remote dir $tdir.2 should fail"
29810
29811         do_nodes $(comma_list $(mdts_nodes)) \
29812                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29813         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29814                 error "create striped dir $tdir.3 should fail"
29815         true
29816 }
29817 run_test 417 "disable remote dir, striped dir and dir migration"
29818
29819 # Checks that the outputs of df [-i] and lfs df [-i] match
29820 #
29821 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29822 check_lfs_df() {
29823         local dir=$2
29824         local inodes
29825         local df_out
29826         local lfs_df_out
29827         local count
29828         local passed=false
29829
29830         # blocks or inodes
29831         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29832
29833         for count in {1..100}; do
29834                 do_nodes "$CLIENTS" \
29835                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29836                 sync; sleep 0.2
29837
29838                 # read the lines of interest
29839                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29840                         error "df $inodes $dir | tail -n +2 failed"
29841                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29842                         error "lfs df $inodes $dir | grep summary: failed"
29843
29844                 # skip first substrings of each output as they are different
29845                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29846                 # compare the two outputs
29847                 passed=true
29848                 #  skip "available" on MDT until LU-13997 is fixed.
29849                 #for i in {1..5}; do
29850                 for i in 1 2 4 5; do
29851                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29852                 done
29853                 $passed && break
29854         done
29855
29856         if ! $passed; then
29857                 df -P $inodes $dir
29858                 echo
29859                 lfs df $inodes $dir
29860                 error "df and lfs df $1 output mismatch: "      \
29861                       "df ${inodes}: ${df_out[*]}, "            \
29862                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29863         fi
29864 }
29865
29866 test_418() {
29867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29868
29869         local dir=$DIR/$tdir
29870         local numfiles=$((RANDOM % 4096 + 2))
29871         local numblocks=$((RANDOM % 256 + 1))
29872
29873         wait_delete_completed
29874         test_mkdir $dir
29875
29876         # check block output
29877         check_lfs_df blocks $dir
29878         # check inode output
29879         check_lfs_df inodes $dir
29880
29881         # create a single file and retest
29882         echo "Creating a single file and testing"
29883         createmany -o $dir/$tfile- 1 &>/dev/null ||
29884                 error "creating 1 file in $dir failed"
29885         check_lfs_df blocks $dir
29886         check_lfs_df inodes $dir
29887
29888         # create a random number of files
29889         echo "Creating $((numfiles - 1)) files and testing"
29890         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29891                 error "creating $((numfiles - 1)) files in $dir failed"
29892
29893         # write a random number of blocks to the first test file
29894         echo "Writing $numblocks 4K blocks and testing"
29895         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29896                 count=$numblocks &>/dev/null ||
29897                 error "dd to $dir/${tfile}-0 failed"
29898
29899         # retest
29900         check_lfs_df blocks $dir
29901         check_lfs_df inodes $dir
29902
29903         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29904                 error "unlinking $numfiles files in $dir failed"
29905 }
29906 run_test 418 "df and lfs df outputs match"
29907
29908 test_419()
29909 {
29910         local dir=$DIR/$tdir
29911
29912         mkdir -p $dir
29913         touch $dir/file
29914
29915         cancel_lru_locks mdc
29916
29917         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29918         $LCTL set_param fail_loc=0x1410
29919         cat $dir/file
29920         $LCTL set_param fail_loc=0
29921         rm -rf $dir
29922 }
29923 run_test 419 "Verify open file by name doesn't crash kernel"
29924
29925 test_420()
29926 {
29927         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29928                 skip "Need MDS version at least 2.12.53"
29929
29930         local SAVE_UMASK=$(umask)
29931         local dir=$DIR/$tdir
29932         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29933
29934         mkdir -p $dir
29935         umask 0000
29936         mkdir -m03777 $dir/testdir
29937         ls -dn $dir/testdir
29938         # Need to remove trailing '.' when SELinux is enabled
29939         local dirperms=$(ls -dn $dir/testdir |
29940                          awk '{ sub(/\.$/, "", $1); print $1}')
29941         [ $dirperms == "drwxrwsrwt" ] ||
29942                 error "incorrect perms on $dir/testdir"
29943
29944         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29945                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29946         ls -n $dir/testdir/testfile
29947         local fileperms=$(ls -n $dir/testdir/testfile |
29948                           awk '{ sub(/\.$/, "", $1); print $1}')
29949         [ $fileperms == "-rwxr-xr-x" ] ||
29950                 error "incorrect perms on $dir/testdir/testfile"
29951
29952         umask $SAVE_UMASK
29953 }
29954 run_test 420 "clear SGID bit on non-directories for non-members"
29955
29956 test_421a() {
29957         local cnt
29958         local fid1
29959         local fid2
29960
29961         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29962                 skip "Need MDS version at least 2.12.54"
29963
29964         test_mkdir $DIR/$tdir
29965         createmany -o $DIR/$tdir/f 3
29966         cnt=$(ls -1 $DIR/$tdir | wc -l)
29967         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29968
29969         fid1=$(lfs path2fid $DIR/$tdir/f1)
29970         fid2=$(lfs path2fid $DIR/$tdir/f2)
29971         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29972
29973         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29974         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29975
29976         cnt=$(ls -1 $DIR/$tdir | wc -l)
29977         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29978
29979         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29980         createmany -o $DIR/$tdir/f 3
29981         cnt=$(ls -1 $DIR/$tdir | wc -l)
29982         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29983
29984         fid1=$(lfs path2fid $DIR/$tdir/f1)
29985         fid2=$(lfs path2fid $DIR/$tdir/f2)
29986         echo "remove using fsname $FSNAME"
29987         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29988
29989         cnt=$(ls -1 $DIR/$tdir | wc -l)
29990         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29991 }
29992 run_test 421a "simple rm by fid"
29993
29994 test_421b() {
29995         local cnt
29996         local FID1
29997         local FID2
29998
29999         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30000                 skip "Need MDS version at least 2.12.54"
30001
30002         test_mkdir $DIR/$tdir
30003         createmany -o $DIR/$tdir/f 3
30004         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
30005         MULTIPID=$!
30006
30007         FID1=$(lfs path2fid $DIR/$tdir/f1)
30008         FID2=$(lfs path2fid $DIR/$tdir/f2)
30009         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
30010
30011         kill -USR1 $MULTIPID
30012         wait
30013
30014         cnt=$(ls $DIR/$tdir | wc -l)
30015         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
30016 }
30017 run_test 421b "rm by fid on open file"
30018
30019 test_421c() {
30020         local cnt
30021         local FIDS
30022
30023         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30024                 skip "Need MDS version at least 2.12.54"
30025
30026         test_mkdir $DIR/$tdir
30027         createmany -o $DIR/$tdir/f 3
30028         touch $DIR/$tdir/$tfile
30029         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
30030         cnt=$(ls -1 $DIR/$tdir | wc -l)
30031         [ $cnt != 184 ] && error "unexpected #files: $cnt"
30032
30033         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
30034         $LFS rmfid $DIR $FID1 || error "rmfid failed"
30035
30036         cnt=$(ls $DIR/$tdir | wc -l)
30037         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
30038 }
30039 run_test 421c "rm by fid against hardlinked files"
30040
30041 test_421d() {
30042         local cnt
30043         local FIDS
30044
30045         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30046                 skip "Need MDS version at least 2.12.54"
30047
30048         test_mkdir $DIR/$tdir
30049         createmany -o $DIR/$tdir/f 4097
30050         cnt=$(ls -1 $DIR/$tdir | wc -l)
30051         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
30052
30053         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
30054         $LFS rmfid $DIR $FIDS || error "rmfid failed"
30055
30056         cnt=$(ls $DIR/$tdir | wc -l)
30057         rm -rf $DIR/$tdir
30058         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30059 }
30060 run_test 421d "rmfid en masse"
30061
30062 test_421e() {
30063         local cnt
30064         local FID
30065
30066         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30067         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30068                 skip "Need MDS version at least 2.12.54"
30069
30070         mkdir -p $DIR/$tdir
30071         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30072         createmany -o $DIR/$tdir/striped_dir/f 512
30073         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30074         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30075
30076         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30077                 sed "s/[/][^:]*://g")
30078         $LFS rmfid $DIR $FIDS || error "rmfid failed"
30079
30080         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30081         rm -rf $DIR/$tdir
30082         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30083 }
30084 run_test 421e "rmfid in DNE"
30085
30086 test_421f() {
30087         local cnt
30088         local FID
30089
30090         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30091                 skip "Need MDS version at least 2.12.54"
30092
30093         test_mkdir $DIR/$tdir
30094         touch $DIR/$tdir/f
30095         cnt=$(ls -1 $DIR/$tdir | wc -l)
30096         [ $cnt != 1 ] && error "unexpected #files: $cnt"
30097
30098         FID=$(lfs path2fid $DIR/$tdir/f)
30099         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
30100         # rmfid should fail
30101         cnt=$(ls -1 $DIR/$tdir | wc -l)
30102         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
30103
30104         chmod a+rw $DIR/$tdir
30105         ls -la $DIR/$tdir
30106         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
30107         # rmfid should fail
30108         cnt=$(ls -1 $DIR/$tdir | wc -l)
30109         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
30110
30111         rm -f $DIR/$tdir/f
30112         $RUNAS touch $DIR/$tdir/f
30113         FID=$(lfs path2fid $DIR/$tdir/f)
30114         echo "rmfid as root"
30115         $LFS rmfid $DIR $FID || error "rmfid as root failed"
30116         cnt=$(ls -1 $DIR/$tdir | wc -l)
30117         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
30118
30119         rm -f $DIR/$tdir/f
30120         $RUNAS touch $DIR/$tdir/f
30121         cnt=$(ls -1 $DIR/$tdir | wc -l)
30122         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
30123         FID=$(lfs path2fid $DIR/$tdir/f)
30124         # rmfid w/o user_fid2path mount option should fail
30125         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
30126         cnt=$(ls -1 $DIR/$tdir | wc -l)
30127         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
30128
30129         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
30130         stack_trap "rmdir $tmpdir"
30131         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
30132                 error "failed to mount client'"
30133         stack_trap "umount_client $tmpdir"
30134
30135         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
30136         # rmfid should succeed
30137         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
30138         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
30139
30140         # rmfid shouldn't allow to remove files due to dir's permission
30141         chmod a+rwx $tmpdir/$tdir
30142         touch $tmpdir/$tdir/f
30143         ls -la $tmpdir/$tdir
30144         FID=$(lfs path2fid $tmpdir/$tdir/f)
30145         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
30146         return 0
30147 }
30148 run_test 421f "rmfid checks permissions"
30149
30150 test_421g() {
30151         local cnt
30152         local FIDS
30153
30154         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30155         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30156                 skip "Need MDS version at least 2.12.54"
30157
30158         mkdir -p $DIR/$tdir
30159         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30160         createmany -o $DIR/$tdir/striped_dir/f 512
30161         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30162         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30163
30164         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30165                 sed "s/[/][^:]*://g")
30166
30167         rm -f $DIR/$tdir/striped_dir/f1*
30168         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30169         removed=$((512 - cnt))
30170
30171         # few files have been just removed, so we expect
30172         # rmfid to fail on their fids
30173         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30174         [ $removed != $errors ] && error "$errors != $removed"
30175
30176         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30177         rm -rf $DIR/$tdir
30178         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30179 }
30180 run_test 421g "rmfid to return errors properly"
30181
30182 test_421h() {
30183         local mount_other
30184         local mount_ret
30185         local rmfid_ret
30186         local old_fid
30187         local fidA
30188         local fidB
30189         local fidC
30190         local fidD
30191
30192         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30193                 skip "Need MDS version at least 2.15.53"
30194
30195         test_mkdir $DIR/$tdir
30196         test_mkdir $DIR/$tdir/subdir
30197         touch $DIR/$tdir/subdir/file0
30198         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30199         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30200         rm -f $DIR/$tdir/subdir/file0
30201         touch $DIR/$tdir/subdir/fileA
30202         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30203         echo File $DIR/$tdir/subdir/fileA FID $fidA
30204         touch $DIR/$tdir/subdir/fileB
30205         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30206         echo File $DIR/$tdir/subdir/fileB FID $fidB
30207         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30208         touch $DIR/$tdir/subdir/fileC
30209         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30210         echo File $DIR/$tdir/subdir/fileC FID $fidC
30211         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30212         touch $DIR/$tdir/fileD
30213         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30214         echo File $DIR/$tdir/fileD FID $fidD
30215
30216         # mount another client mount point with subdirectory mount
30217         export FILESET=/$tdir/subdir
30218         mount_other=${MOUNT}_other
30219         mount_client $mount_other ${MOUNT_OPTS}
30220         mount_ret=$?
30221         export FILESET=""
30222         (( mount_ret == 0 )) || error "mount $mount_other failed"
30223
30224         echo Removing FIDs:
30225         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30226         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30227         rmfid_ret=$?
30228
30229         umount_client $mount_other || error "umount $mount_other failed"
30230
30231         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30232
30233         # fileA should have been deleted
30234         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30235
30236         # fileB should have been deleted
30237         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30238
30239         # fileC should not have been deleted, fid also exists outside of fileset
30240         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30241
30242         # fileD should not have been deleted, it exists outside of fileset
30243         stat $DIR/$tdir/fileD || error "fileD deleted"
30244 }
30245 run_test 421h "rmfid with fileset mount"
30246
30247 test_422() {
30248         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30249         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30250         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30251         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30252         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30253
30254         local amc=$(at_max_get client)
30255         local amo=$(at_max_get mds1)
30256         local timeout=`lctl get_param -n timeout`
30257
30258         at_max_set 0 client
30259         at_max_set 0 mds1
30260
30261 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30262         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30263                         fail_val=$(((2*timeout + 10)*1000))
30264         touch $DIR/$tdir/d3/file &
30265         sleep 2
30266 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30267         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30268                         fail_val=$((2*timeout + 5))
30269         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30270         local pid=$!
30271         sleep 1
30272         kill -9 $pid
30273         sleep $((2 * timeout))
30274         echo kill $pid
30275         kill -9 $pid
30276         lctl mark touch
30277         touch $DIR/$tdir/d2/file3
30278         touch $DIR/$tdir/d2/file4
30279         touch $DIR/$tdir/d2/file5
30280
30281         wait
30282         at_max_set $amc client
30283         at_max_set $amo mds1
30284
30285         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30286         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30287                 error "Watchdog is always throttled"
30288 }
30289 run_test 422 "kill a process with RPC in progress"
30290
30291 stat_test() {
30292     df -h $MOUNT &
30293     df -h $MOUNT &
30294     df -h $MOUNT &
30295     df -h $MOUNT &
30296     df -h $MOUNT &
30297     df -h $MOUNT &
30298 }
30299
30300 test_423() {
30301     local _stats
30302     # ensure statfs cache is expired
30303     sleep 2;
30304
30305     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30306     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30307
30308     return 0
30309 }
30310 run_test 423 "statfs should return a right data"
30311
30312 test_424() {
30313 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30314         $LCTL set_param fail_loc=0x80000522
30315         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30316         rm -f $DIR/$tfile
30317 }
30318 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30319
30320 test_425() {
30321         test_mkdir -c -1 $DIR/$tdir
30322         $LFS setstripe -c -1 $DIR/$tdir
30323
30324         lru_resize_disable "" 100
30325         stack_trap "lru_resize_enable" EXIT
30326
30327         sleep 5
30328
30329         for i in $(seq $((MDSCOUNT * 125))); do
30330                 local t=$DIR/$tdir/$tfile_$i
30331
30332                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30333                         error_noexit "Create file $t"
30334         done
30335         stack_trap "rm -rf $DIR/$tdir" EXIT
30336
30337         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30338                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30339                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30340
30341                 [ $lock_count -le $lru_size ] ||
30342                         error "osc lock count $lock_count > lru size $lru_size"
30343         done
30344
30345         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30346                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30347                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30348
30349                 [ $lock_count -le $lru_size ] ||
30350                         error "mdc lock count $lock_count > lru size $lru_size"
30351         done
30352 }
30353 run_test 425 "lock count should not exceed lru size"
30354
30355 test_426() {
30356         splice-test -r $DIR/$tfile
30357         splice-test -rd $DIR/$tfile
30358         splice-test $DIR/$tfile
30359         splice-test -d $DIR/$tfile
30360 }
30361 run_test 426 "splice test on Lustre"
30362
30363 test_427() {
30364         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30365         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30366                 skip "Need MDS version at least 2.12.4"
30367         local log
30368
30369         mkdir $DIR/$tdir
30370         mkdir $DIR/$tdir/1
30371         mkdir $DIR/$tdir/2
30372         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30373         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30374
30375         $LFS getdirstripe $DIR/$tdir/1/dir
30376
30377         #first setfattr for creating updatelog
30378         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30379
30380 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30381         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30382         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30383         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30384
30385         sleep 2
30386         fail mds2
30387         wait_recovery_complete mds2 $((2*TIMEOUT))
30388
30389         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30390         echo $log | grep "get update log failed" &&
30391                 error "update log corruption is detected" || true
30392 }
30393 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30394
30395 test_428() {
30396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30397         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30398                               awk '/^max_cached_mb/ { print $2 }')
30399         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30400
30401         $LCTL set_param -n llite.*.max_cached_mb=64
30402
30403         mkdir $DIR/$tdir
30404         $LFS setstripe -c 1 $DIR/$tdir
30405         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30406         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30407         #test write
30408         for f in $(seq 4); do
30409                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30410         done
30411         wait
30412
30413         cancel_lru_locks osc
30414         # Test read
30415         for f in $(seq 4); do
30416                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30417         done
30418         wait
30419 }
30420 run_test 428 "large block size IO should not hang"
30421
30422 test_429() { # LU-7915 / LU-10948
30423         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30424         local testfile=$DIR/$tfile
30425         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30426         local new_flag=1
30427         local first_rpc
30428         local second_rpc
30429         local third_rpc
30430
30431         $LCTL get_param $ll_opencache_threshold_count ||
30432                 skip "client does not have opencache parameter"
30433
30434         set_opencache $new_flag
30435         stack_trap "restore_opencache"
30436         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30437                 error "enable opencache failed"
30438         touch $testfile
30439         # drop MDC DLM locks
30440         cancel_lru_locks mdc
30441         # clear MDC RPC stats counters
30442         $LCTL set_param $mdc_rpcstats=clear
30443
30444         # According to the current implementation, we need to run 3 times
30445         # open & close file to verify if opencache is enabled correctly.
30446         # 1st, RPCs are sent for lookup/open and open handle is released on
30447         #      close finally.
30448         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30449         #      so open handle won't be released thereafter.
30450         # 3rd, No RPC is sent out.
30451         $MULTIOP $testfile oc || error "multiop failed"
30452         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30453         echo "1st: $first_rpc RPCs in flight"
30454
30455         $MULTIOP $testfile oc || error "multiop failed"
30456         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30457         echo "2nd: $second_rpc RPCs in flight"
30458
30459         $MULTIOP $testfile oc || error "multiop failed"
30460         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30461         echo "3rd: $third_rpc RPCs in flight"
30462
30463         #verify no MDC RPC is sent
30464         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30465 }
30466 run_test 429 "verify if opencache flag on client side does work"
30467
30468 lseek_test_430() {
30469         local offset
30470         local file=$1
30471
30472         # data at [200K, 400K)
30473         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30474                 error "256K->512K dd fails"
30475         # data at [2M, 3M)
30476         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30477                 error "2M->3M dd fails"
30478         # data at [4M, 5M)
30479         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30480                 error "4M->5M dd fails"
30481         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30482         # start at first component hole #1
30483         printf "Seeking hole from 1000 ... "
30484         offset=$(lseek_test -l 1000 $file)
30485         echo $offset
30486         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30487         printf "Seeking data from 1000 ... "
30488         offset=$(lseek_test -d 1000 $file)
30489         echo $offset
30490         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30491
30492         # start at first component data block
30493         printf "Seeking hole from 300000 ... "
30494         offset=$(lseek_test -l 300000 $file)
30495         echo $offset
30496         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30497         printf "Seeking data from 300000 ... "
30498         offset=$(lseek_test -d 300000 $file)
30499         echo $offset
30500         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30501
30502         # start at the first component but beyond end of object size
30503         printf "Seeking hole from 1000000 ... "
30504         offset=$(lseek_test -l 1000000 $file)
30505         echo $offset
30506         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30507         printf "Seeking data from 1000000 ... "
30508         offset=$(lseek_test -d 1000000 $file)
30509         echo $offset
30510         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30511
30512         # start at second component stripe 2 (empty file)
30513         printf "Seeking hole from 1500000 ... "
30514         offset=$(lseek_test -l 1500000 $file)
30515         echo $offset
30516         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30517         printf "Seeking data from 1500000 ... "
30518         offset=$(lseek_test -d 1500000 $file)
30519         echo $offset
30520         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30521
30522         # start at second component stripe 1 (all data)
30523         printf "Seeking hole from 3000000 ... "
30524         offset=$(lseek_test -l 3000000 $file)
30525         echo $offset
30526         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30527         printf "Seeking data from 3000000 ... "
30528         offset=$(lseek_test -d 3000000 $file)
30529         echo $offset
30530         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30531
30532         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30533                 error "2nd dd fails"
30534         echo "Add data block at 640K...1280K"
30535
30536         # start at before new data block, in hole
30537         printf "Seeking hole from 600000 ... "
30538         offset=$(lseek_test -l 600000 $file)
30539         echo $offset
30540         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30541         printf "Seeking data from 600000 ... "
30542         offset=$(lseek_test -d 600000 $file)
30543         echo $offset
30544         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30545
30546         # start at the first component new data block
30547         printf "Seeking hole from 1000000 ... "
30548         offset=$(lseek_test -l 1000000 $file)
30549         echo $offset
30550         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30551         printf "Seeking data from 1000000 ... "
30552         offset=$(lseek_test -d 1000000 $file)
30553         echo $offset
30554         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30555
30556         # start at second component stripe 2, new data
30557         printf "Seeking hole from 1200000 ... "
30558         offset=$(lseek_test -l 1200000 $file)
30559         echo $offset
30560         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30561         printf "Seeking data from 1200000 ... "
30562         offset=$(lseek_test -d 1200000 $file)
30563         echo $offset
30564         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30565
30566         # start beyond file end
30567         printf "Using offset > filesize ... "
30568         lseek_test -l 4000000 $file && error "lseek should fail"
30569         printf "Using offset > filesize ... "
30570         lseek_test -d 4000000 $file && error "lseek should fail"
30571
30572         printf "Done\n\n"
30573 }
30574
30575 test_430a() {
30576         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30577                 skip "MDT does not support SEEK_HOLE"
30578
30579         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30580                 skip "OST does not support SEEK_HOLE"
30581
30582         local file=$DIR/$tdir/$tfile
30583
30584         mkdir -p $DIR/$tdir
30585
30586         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30587         # OST stripe #1 will have continuous data at [1M, 3M)
30588         # OST stripe #2 is empty
30589         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30590         lseek_test_430 $file
30591         rm $file
30592         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30593         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30594         lseek_test_430 $file
30595         rm $file
30596         $LFS setstripe -c2 -S 512K $file
30597         echo "Two stripes, stripe size 512K"
30598         lseek_test_430 $file
30599         rm $file
30600         # FLR with stale mirror
30601         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30602                        -N -c2 -S 1M $file
30603         echo "Mirrored file:"
30604         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30605         echo "Plain 2 stripes 1M"
30606         lseek_test_430 $file
30607         rm $file
30608 }
30609 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30610
30611 test_430b() {
30612         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30613                 skip "OST does not support SEEK_HOLE"
30614
30615         local offset
30616         local file=$DIR/$tdir/$tfile
30617
30618         mkdir -p $DIR/$tdir
30619         # Empty layout lseek should fail
30620         $MCREATE $file
30621         # seek from 0
30622         printf "Seeking hole from 0 ... "
30623         lseek_test -l 0 $file && error "lseek should fail"
30624         printf "Seeking data from 0 ... "
30625         lseek_test -d 0 $file && error "lseek should fail"
30626         rm $file
30627
30628         # 1M-hole file
30629         $LFS setstripe -E 1M -c2 -E eof $file
30630         $TRUNCATE $file 1048576
30631         printf "Seeking hole from 1000000 ... "
30632         offset=$(lseek_test -l 1000000 $file)
30633         echo $offset
30634         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30635         printf "Seeking data from 1000000 ... "
30636         lseek_test -d 1000000 $file && error "lseek should fail"
30637         rm $file
30638
30639         # full component followed by non-inited one
30640         $LFS setstripe -E 1M -c2 -E eof $file
30641         dd if=/dev/urandom of=$file bs=1M count=1
30642         printf "Seeking hole from 1000000 ... "
30643         offset=$(lseek_test -l 1000000 $file)
30644         echo $offset
30645         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30646         printf "Seeking hole from 1048576 ... "
30647         lseek_test -l 1048576 $file && error "lseek should fail"
30648         # init second component and truncate back
30649         echo "123" >> $file
30650         $TRUNCATE $file 1048576
30651         printf "Seeking hole from 1000000 ... "
30652         offset=$(lseek_test -l 1000000 $file)
30653         echo $offset
30654         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30655         printf "Seeking hole from 1048576 ... "
30656         lseek_test -l 1048576 $file && error "lseek should fail"
30657         # boundary checks for big values
30658         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30659         offset=$(lseek_test -d 0 $file.10g)
30660         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30661         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30662         offset=$(lseek_test -d 0 $file.100g)
30663         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30664         return 0
30665 }
30666 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30667
30668 test_430c() {
30669         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30670                 skip "OST does not support SEEK_HOLE"
30671
30672         local file=$DIR/$tdir/$tfile
30673         local start
30674
30675         mkdir -p $DIR/$tdir
30676         stack_trap "rm -f $file $file.tmp"
30677         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30678
30679         # cp version 8.33+ prefers lseek over fiemap
30680         local ver=$(cp --version | awk '{ print $4; exit; }')
30681
30682         echo "cp $ver installed"
30683         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30684                 start=$SECONDS
30685                 time cp -v $file $file.tmp || error "cp $file failed"
30686                 (( SECONDS - start < 5 )) || {
30687                         strace cp $file $file.tmp |&
30688                                 grep -E "open|read|seek|FIEMAP" |
30689                                 grep -A 100 $file
30690                         error "cp: too long runtime $((SECONDS - start))"
30691                 }
30692         else
30693                 echo "cp test skipped due to $ver < 8.33"
30694         fi
30695
30696         # tar version 1.29+ supports SEEK_HOLE/DATA
30697         ver=$(tar --version | awk '{ print $4; exit; }')
30698         echo "tar $ver installed"
30699         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30700                 start=$SECONDS
30701                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30702                 (( SECONDS - start < 5 )) || {
30703                         strace tar cf $file.tmp --sparse $file |&
30704                                 grep -E "open|read|seek|FIEMAP" |
30705                                 grep -A 100 $file
30706                         error "tar: too long runtime $((SECONDS - start))"
30707                 }
30708         else
30709                 echo "tar test skipped due to $ver < 1.29"
30710         fi
30711 }
30712 run_test 430c "lseek: external tools check"
30713
30714 test_431() { # LU-14187
30715         local file=$DIR/$tdir/$tfile
30716
30717         mkdir -p $DIR/$tdir
30718         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30719         dd if=/dev/urandom of=$file bs=4k count=1
30720         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30721         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30722         #define OBD_FAIL_OST_RESTART_IO 0x251
30723         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30724         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30725         cp $file $file.0
30726         cancel_lru_locks
30727         sync_all_data
30728         echo 3 > /proc/sys/vm/drop_caches
30729         diff  $file $file.0 || error "data diff"
30730 }
30731 run_test 431 "Restart transaction for IO"
30732
30733 cleanup_test_432() {
30734         do_facet mgs $LCTL nodemap_activate 0
30735         wait_nm_sync active
30736 }
30737
30738 test_432() {
30739         local tmpdir=$TMP/dir432
30740
30741         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30742                 skip "Need MDS version at least 2.14.52"
30743
30744         stack_trap cleanup_test_432 EXIT
30745         mkdir $DIR/$tdir
30746         mkdir $tmpdir
30747
30748         do_facet mgs $LCTL nodemap_activate 1
30749         wait_nm_sync active
30750         do_facet mgs $LCTL nodemap_modify --name default \
30751                 --property admin --value 1
30752         do_facet mgs $LCTL nodemap_modify --name default \
30753                 --property trusted --value 1
30754         cancel_lru_locks mdc
30755         wait_nm_sync default admin_nodemap
30756         wait_nm_sync default trusted_nodemap
30757
30758         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30759                grep -ci "Operation not permitted") -ne 0 ]; then
30760                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30761         fi
30762 }
30763 run_test 432 "mv dir from outside Lustre"
30764
30765 test_433() {
30766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30767
30768         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30769                 skip "inode cache not supported"
30770
30771         $LCTL set_param llite.*.inode_cache=0
30772         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30773
30774         local count=256
30775         local before
30776         local after
30777
30778         cancel_lru_locks mdc
30779         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30780         createmany -m $DIR/$tdir/f $count
30781         createmany -d $DIR/$tdir/d $count
30782         ls -l $DIR/$tdir > /dev/null
30783         stack_trap "rm -rf $DIR/$tdir"
30784
30785         before=$(num_objects)
30786         cancel_lru_locks mdc
30787         after=$(num_objects)
30788
30789         # sometimes even @before is less than 2 * count
30790         while (( before - after < count )); do
30791                 sleep 1
30792                 after=$(num_objects)
30793                 wait=$((wait + 1))
30794                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30795                 if (( wait > 60 )); then
30796                         error "inode slab grew from $before to $after"
30797                 fi
30798         done
30799
30800         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30801 }
30802 run_test 433 "ldlm lock cancel releases dentries and inodes"
30803
30804 test_434() {
30805         local file
30806         local getxattr_count
30807         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30808         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30809
30810         [[ $(getenforce) == "Disabled" ]] ||
30811                 skip "lsm selinux module have to be disabled for this test"
30812
30813         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30814                 error "fail to create $DIR/$tdir/ on MDT0000"
30815
30816         touch $DIR/$tdir/$tfile-{001..100}
30817
30818         # disable the xattr cache
30819         save_lustre_params client "llite.*.xattr_cache" > $p
30820         lctl set_param llite.*.xattr_cache=0
30821         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30822
30823         # clear clients mdc stats
30824         clear_stats $mdc_stat_param ||
30825                 error "fail to clear stats on mdc MDT0000"
30826
30827         for file in $DIR/$tdir/$tfile-{001..100}; do
30828                 getfattr -n security.selinux $file |&
30829                         grep -q "Operation not supported" ||
30830                         error "getxattr on security.selinux should return EOPNOTSUPP"
30831         done
30832
30833         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30834         (( getxattr_count < 100 )) ||
30835                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30836 }
30837 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30838
30839 test_440() {
30840         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30841                 source $LUSTRE/scripts/bash-completion/lustre
30842         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30843                 source /usr/share/bash-completion/completions/lustre
30844         else
30845                 skip "bash completion scripts not found"
30846         fi
30847
30848         local lctl_completions
30849         local lfs_completions
30850
30851         lctl_completions=$(_lustre_cmds lctl)
30852         if [[ ! $lctl_completions =~ "get_param" ]]; then
30853                 error "lctl bash completion failed"
30854         fi
30855
30856         lfs_completions=$(_lustre_cmds lfs)
30857         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30858                 error "lfs bash completion failed"
30859         fi
30860 }
30861 run_test 440 "bash completion for lfs, lctl"
30862
30863 test_442() {
30864         local pid1
30865         local pid2
30866         mkdir -p $DIR/$tdir
30867         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30868         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30869         sleep 1
30870         touch $DIR/$tdir/$tfile.2
30871         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30872         $LCTL set_param fail_loc=0x1430
30873         kill -USR1 $pid1
30874         sleep 1
30875         kill -USR1 $pid2
30876         wait
30877 }
30878 run_test 442 "truncate vs read/write should not panic"
30879
30880 test_460d() {
30881         verify_yaml_available || skip_env "YAML verification not installed"
30882         $LCTL get_param -n sptlrpc.page_pools
30883         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30884                 error "The output of encrypt_page_pools is not an valid YAML"
30885 }
30886 run_test 460d "Check encrypt pools output"
30887
30888 prep_801() {
30889         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30890         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30891                 skip "Need server version at least 2.9.55"
30892
30893         start_full_debug_logging
30894 }
30895
30896 post_801() {
30897         stop_full_debug_logging
30898 }
30899
30900 barrier_stat() {
30901         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30902                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30903                            awk '/The barrier for/ { print $7 }')
30904                 echo $st
30905         else
30906                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30907                 echo \'$st\'
30908         fi
30909 }
30910
30911 barrier_expired() {
30912         local expired
30913
30914         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30915                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30916                           awk '/will be expired/ { print $7 }')
30917         else
30918                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30919         fi
30920
30921         echo $expired
30922 }
30923
30924 test_801a() {
30925         prep_801
30926
30927         echo "Start barrier_freeze at: $(date)"
30928         #define OBD_FAIL_BARRIER_DELAY          0x2202
30929         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30930         # Do not reduce barrier time - See LU-11873
30931         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30932
30933         sleep 2
30934         local b_status=$(barrier_stat)
30935         echo "Got barrier status at: $(date)"
30936         [ "$b_status" = "'freezing_p1'" ] ||
30937                 error "(1) unexpected barrier status $b_status"
30938
30939         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30940         wait
30941         b_status=$(barrier_stat)
30942         [ "$b_status" = "'frozen'" ] ||
30943                 error "(2) unexpected barrier status $b_status"
30944
30945         local expired=$(barrier_expired)
30946         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30947         sleep $((expired + 3))
30948
30949         b_status=$(barrier_stat)
30950         [ "$b_status" = "'expired'" ] ||
30951                 error "(3) unexpected barrier status $b_status"
30952
30953         # Do not reduce barrier time - See LU-11873
30954         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30955                 error "(4) fail to freeze barrier"
30956
30957         b_status=$(barrier_stat)
30958         [ "$b_status" = "'frozen'" ] ||
30959                 error "(5) unexpected barrier status $b_status"
30960
30961         echo "Start barrier_thaw at: $(date)"
30962         #define OBD_FAIL_BARRIER_DELAY          0x2202
30963         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30964         do_facet mgs $LCTL barrier_thaw $FSNAME &
30965
30966         sleep 2
30967         b_status=$(barrier_stat)
30968         echo "Got barrier status at: $(date)"
30969         [ "$b_status" = "'thawing'" ] ||
30970                 error "(6) unexpected barrier status $b_status"
30971
30972         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30973         wait
30974         b_status=$(barrier_stat)
30975         [ "$b_status" = "'thawed'" ] ||
30976                 error "(7) unexpected barrier status $b_status"
30977
30978         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30979         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30980         do_facet mgs $LCTL barrier_freeze $FSNAME
30981
30982         b_status=$(barrier_stat)
30983         [ "$b_status" = "'failed'" ] ||
30984                 error "(8) unexpected barrier status $b_status"
30985
30986         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30987         do_facet mgs $LCTL barrier_thaw $FSNAME
30988
30989         post_801
30990 }
30991 run_test 801a "write barrier user interfaces and stat machine"
30992
30993 test_801b() {
30994         prep_801
30995
30996         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30997         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30998         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30999         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
31000         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
31001
31002         cancel_lru_locks mdc
31003
31004         # 180 seconds should be long enough
31005         do_facet mgs $LCTL barrier_freeze $FSNAME 180
31006
31007         local b_status=$(barrier_stat)
31008         [ "$b_status" = "'frozen'" ] ||
31009                 error "(6) unexpected barrier status $b_status"
31010
31011         mkdir $DIR/$tdir/d0/d10 &
31012         mkdir_pid=$!
31013
31014         touch $DIR/$tdir/d1/f13 &
31015         touch_pid=$!
31016
31017         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
31018         ln_pid=$!
31019
31020         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
31021         mv_pid=$!
31022
31023         rm -f $DIR/$tdir/d4/f12 &
31024         rm_pid=$!
31025
31026         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
31027
31028         # To guarantee taht the 'stat' is not blocked
31029         b_status=$(barrier_stat)
31030         [ "$b_status" = "'frozen'" ] ||
31031                 error "(8) unexpected barrier status $b_status"
31032
31033         # let above commands to run at background
31034         sleep 5
31035
31036         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
31037         ps -p $touch_pid || error "(10) touch should be blocked"
31038         ps -p $ln_pid || error "(11) link should be blocked"
31039         ps -p $mv_pid || error "(12) rename should be blocked"
31040         ps -p $rm_pid || error "(13) unlink should be blocked"
31041
31042         b_status=$(barrier_stat)
31043         [ "$b_status" = "'frozen'" ] ||
31044                 error "(14) unexpected barrier status $b_status"
31045
31046         do_facet mgs $LCTL barrier_thaw $FSNAME
31047         b_status=$(barrier_stat)
31048         [ "$b_status" = "'thawed'" ] ||
31049                 error "(15) unexpected barrier status $b_status"
31050
31051         wait $mkdir_pid || error "(16) mkdir should succeed"
31052         wait $touch_pid || error "(17) touch should succeed"
31053         wait $ln_pid || error "(18) link should succeed"
31054         wait $mv_pid || error "(19) rename should succeed"
31055         wait $rm_pid || error "(20) unlink should succeed"
31056
31057         post_801
31058 }
31059 run_test 801b "modification will be blocked by write barrier"
31060
31061 test_801c() {
31062         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31063
31064         prep_801
31065
31066         stop mds2 || error "(1) Fail to stop mds2"
31067
31068         do_facet mgs $LCTL barrier_freeze $FSNAME 30
31069
31070         local b_status=$(barrier_stat)
31071         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
31072                 do_facet mgs $LCTL barrier_thaw $FSNAME
31073                 error "(2) unexpected barrier status $b_status"
31074         }
31075
31076         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31077                 error "(3) Fail to rescan barrier bitmap"
31078
31079         # Do not reduce barrier time - See LU-11873
31080         do_facet mgs $LCTL barrier_freeze $FSNAME 20
31081
31082         b_status=$(barrier_stat)
31083         [ "$b_status" = "'frozen'" ] ||
31084                 error "(4) unexpected barrier status $b_status"
31085
31086         do_facet mgs $LCTL barrier_thaw $FSNAME
31087         b_status=$(barrier_stat)
31088         [ "$b_status" = "'thawed'" ] ||
31089                 error "(5) unexpected barrier status $b_status"
31090
31091         local devname=$(mdsdevname 2)
31092
31093         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
31094
31095         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31096                 error "(7) Fail to rescan barrier bitmap"
31097
31098         post_801
31099 }
31100 run_test 801c "rescan barrier bitmap"
31101
31102 test_802b() {
31103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31104         remote_mds_nodsh && skip "remote MDS with nodsh"
31105
31106         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
31107                 skip "readonly option not available"
31108
31109         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
31110
31111         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
31112                 error "(2) Fail to copy"
31113
31114         # write back all cached data before setting MDT to readonly
31115         cancel_lru_locks
31116         sync_all_data
31117
31118         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
31119         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
31120
31121         echo "Modify should be refused"
31122         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
31123
31124         echo "Read should be allowed"
31125         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
31126                 error "(7) Read should succeed under ro mode"
31127
31128         # disable readonly
31129         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
31130 }
31131 run_test 802b "be able to set MDTs to readonly"
31132
31133 test_803a() {
31134         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31135         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31136                 skip "MDS needs to be newer than 2.10.54"
31137
31138         mkdir_on_mdt0 $DIR/$tdir
31139         # Create some objects on all MDTs to trigger related logs objects
31140         for idx in $(seq $MDSCOUNT); do
31141                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
31142                         $DIR/$tdir/dir${idx} ||
31143                         error "Fail to create $DIR/$tdir/dir${idx}"
31144         done
31145
31146         wait_delete_completed # ensure old test cleanups are finished
31147         sleep 3
31148         echo "before create:"
31149         $LFS df -i $MOUNT
31150         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31151
31152         for i in {1..10}; do
31153                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31154                         error "Fail to create $DIR/$tdir/foo$i"
31155         done
31156
31157         # sync ZFS-on-MDS to refresh statfs data
31158         wait_zfs_commit mds1
31159         sleep 3
31160         echo "after create:"
31161         $LFS df -i $MOUNT
31162         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31163
31164         # allow for an llog to be cleaned up during the test
31165         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31166                 error "before ($before_used) + 10 > after ($after_used)"
31167
31168         for i in {1..10}; do
31169                 rm -rf $DIR/$tdir/foo$i ||
31170                         error "Fail to remove $DIR/$tdir/foo$i"
31171         done
31172
31173         # sync ZFS-on-MDS to refresh statfs data
31174         wait_zfs_commit mds1
31175         wait_delete_completed
31176         sleep 3 # avoid MDT return cached statfs
31177         echo "after unlink:"
31178         $LFS df -i $MOUNT
31179         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31180
31181         # allow for an llog to be created during the test
31182         [ $after_used -le $((before_used + 1)) ] ||
31183                 error "after ($after_used) > before ($before_used) + 1"
31184 }
31185 run_test 803a "verify agent object for remote object"
31186
31187 test_803b() {
31188         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31189         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31190                 skip "MDS needs to be newer than 2.13.56"
31191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31192
31193         for i in $(seq 0 $((MDSCOUNT - 1))); do
31194                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31195         done
31196
31197         local before=0
31198         local after=0
31199
31200         local tmp
31201
31202         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31203         for i in $(seq 0 $((MDSCOUNT - 1))); do
31204                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31205                         awk '/getattr/ { print $2 }')
31206                 before=$((before + tmp))
31207         done
31208         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31209         for i in $(seq 0 $((MDSCOUNT - 1))); do
31210                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31211                         awk '/getattr/ { print $2 }')
31212                 after=$((after + tmp))
31213         done
31214
31215         [ $before -eq $after ] || error "getattr count $before != $after"
31216 }
31217 run_test 803b "remote object can getattr from cache"
31218
31219 test_804() {
31220         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31221         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31222                 skip "MDS needs to be newer than 2.10.54"
31223         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31224
31225         mkdir -p $DIR/$tdir
31226         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31227                 error "Fail to create $DIR/$tdir/dir0"
31228
31229         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31230         local dev=$(mdsdevname 2)
31231
31232         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31233                 grep ${fid} || error "NOT found agent entry for dir0"
31234
31235         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31236                 error "Fail to create $DIR/$tdir/dir1"
31237
31238         touch $DIR/$tdir/dir1/foo0 ||
31239                 error "Fail to create $DIR/$tdir/dir1/foo0"
31240         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31241         local rc=0
31242
31243         for idx in $(seq $MDSCOUNT); do
31244                 dev=$(mdsdevname $idx)
31245                 do_facet mds${idx} \
31246                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31247                         grep ${fid} && rc=$idx
31248         done
31249
31250         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31251                 error "Fail to rename foo0 to foo1"
31252         if [ $rc -eq 0 ]; then
31253                 for idx in $(seq $MDSCOUNT); do
31254                         dev=$(mdsdevname $idx)
31255                         do_facet mds${idx} \
31256                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31257                         grep ${fid} && rc=$idx
31258                 done
31259         fi
31260
31261         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31262                 error "Fail to rename foo1 to foo2"
31263         if [ $rc -eq 0 ]; then
31264                 for idx in $(seq $MDSCOUNT); do
31265                         dev=$(mdsdevname $idx)
31266                         do_facet mds${idx} \
31267                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31268                         grep ${fid} && rc=$idx
31269                 done
31270         fi
31271
31272         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31273
31274         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31275                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31276         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31277                 error "Fail to rename foo2 to foo0"
31278         unlink $DIR/$tdir/dir1/foo0 ||
31279                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31280         rm -rf $DIR/$tdir/dir0 ||
31281                 error "Fail to rm $DIR/$tdir/dir0"
31282
31283         for idx in $(seq $MDSCOUNT); do
31284                 rc=0
31285
31286                 stop mds${idx}
31287                 dev=$(mdsdevname $idx)
31288                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31289                         rc=$?
31290                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31291                         error "mount mds$idx failed"
31292                 df $MOUNT > /dev/null 2>&1
31293
31294                 # e2fsck should not return error
31295                 [ $rc -eq 0 ] ||
31296                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31297         done
31298 }
31299 run_test 804 "verify agent entry for remote entry"
31300
31301 cleanup_805() {
31302         do_facet $SINGLEMDS zfs set quota=$old $fsset
31303         unlinkmany $DIR/$tdir/f- 1000000
31304         trap 0
31305 }
31306
31307 test_805() {
31308         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31309         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31310         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31311                 skip "netfree not implemented before 0.7"
31312         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31313                 skip "Need MDS version at least 2.10.57"
31314
31315         local fsset
31316         local freekb
31317         local usedkb
31318         local old
31319         local quota
31320         local pref="osd-zfs.$FSNAME-MDT0000."
31321
31322         # limit available space on MDS dataset to meet nospace issue
31323         # quickly. then ZFS 0.7.2 can use reserved space if asked
31324         # properly (using netfree flag in osd_declare_destroy()
31325         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31326         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31327                 gawk '{print $3}')
31328         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31329         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31330         let "usedkb=usedkb-freekb"
31331         let "freekb=freekb/2"
31332         if let "freekb > 5000"; then
31333                 let "freekb=5000"
31334         fi
31335         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31336         trap cleanup_805 EXIT
31337         mkdir_on_mdt0 $DIR/$tdir
31338         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31339                 error "Can't set PFL layout"
31340         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31341         rm -rf $DIR/$tdir || error "not able to remove"
31342         do_facet $SINGLEMDS zfs set quota=$old $fsset
31343         trap 0
31344 }
31345 run_test 805 "ZFS can remove from full fs"
31346
31347 # Size-on-MDS test
31348 check_lsom_data()
31349 {
31350         local file=$1
31351         local expect=$(stat -c %s $file)
31352         local msg=$2
31353
31354         check_lsom_size $1 $expect $msg
31355
31356         local blocks=$($LFS getsom -b $file)
31357         expect=$(stat -c %b $file)
31358         [[ $blocks == $expect ]] ||
31359                 error "$msg $file expected blocks: $expect, got: $blocks"
31360 }
31361
31362 check_lsom_size()
31363 {
31364         local size
31365         local expect=$2
31366         local msg=$3
31367
31368         cancel_lru_locks mdc
31369
31370         size=$($LFS getsom -s $1)
31371         [[ $size == $expect ]] ||
31372                 error "$msg $file expected size: $expect, got: $size"
31373 }
31374
31375 test_806() {
31376         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31377                 skip "Need MDS version at least 2.11.52"
31378
31379         local bs=1048576
31380
31381         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31382
31383         disable_opencache
31384         stack_trap "restore_opencache"
31385
31386         # single-threaded write
31387         echo "Test SOM for single-threaded write"
31388         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31389                 error "write $tfile failed"
31390         check_lsom_size $DIR/$tfile $bs "(0)"
31391         # Test SOM with DIO write (dd truncates to 0)
31392         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 oflag=direct ||
31393                 error "write $tfile failed"
31394         check_lsom_size $DIR/$tfile $bs "(1)"
31395
31396         local num=32
31397         local size=$(($num * $bs))
31398         local offset=0
31399         local i
31400
31401         echo "Test SOM for single client multi-threaded($num) write"
31402         $TRUNCATE $DIR/$tfile 0
31403         for ((i = 0; i < $num; i++)); do
31404                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31405                 local pids[$i]=$!
31406                 offset=$((offset + $bs))
31407         done
31408         for (( i=0; i < $num; i++ )); do
31409                 wait ${pids[$i]}
31410         done
31411         check_lsom_size $DIR/$tfile $size "(2)"
31412
31413         $TRUNCATE $DIR/$tfile 0
31414         for ((i = 0; i < $num; i++)); do
31415                 offset=$((offset - $bs))
31416                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31417                 local pids[$i]=$!
31418         done
31419         for (( i=0; i < $num; i++ )); do
31420                 wait ${pids[$i]}
31421         done
31422         check_lsom_size $DIR/$tfile $size "(3)"
31423
31424         # multi-client writes
31425         num=$(get_node_count ${CLIENTS//,/ })
31426         size=$(($num * $bs))
31427         offset=0
31428         i=0
31429
31430         echo "Test SOM for multi-client ($num) writes"
31431         $TRUNCATE $DIR/$tfile 0
31432         for client in ${CLIENTS//,/ }; do
31433                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31434                 local pids[$i]=$!
31435                 i=$((i + 1))
31436                 offset=$((offset + $bs))
31437         done
31438         for (( i=0; i < $num; i++ )); do
31439                 wait ${pids[$i]}
31440         done
31441         check_lsom_size $DIR/$tfile $offset "(4)"
31442
31443         i=0
31444         $TRUNCATE $DIR/$tfile 0
31445         for client in ${CLIENTS//,/ }; do
31446                 offset=$((offset - $bs))
31447                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31448                 local pids[$i]=$!
31449                 i=$((i + 1))
31450         done
31451         for (( i=0; i < $num; i++ )); do
31452                 wait ${pids[$i]}
31453         done
31454         check_lsom_size $DIR/$tfile $size "(5)"
31455
31456         # verify SOM blocks count
31457         echo "Verify SOM block count"
31458         $TRUNCATE $DIR/$tfile 0
31459         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31460                 error "failed to write file $tfile with fdatasync and fstat"
31461         check_lsom_data $DIR/$tfile "(6)"
31462
31463         $TRUNCATE $DIR/$tfile 0
31464         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31465                 error "failed to write file $tfile with fdatasync"
31466         check_lsom_data $DIR/$tfile "(7)"
31467
31468         $TRUNCATE $DIR/$tfile 0
31469         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31470                 error "failed to write file $tfile with sync IO"
31471         check_lsom_data $DIR/$tfile "(8)"
31472
31473         # verify truncate
31474         echo "Test SOM for truncate"
31475         # use ftruncate to sync blocks on close request
31476         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31477         check_lsom_size $DIR/$tfile 16384 "(9)"
31478         check_lsom_data $DIR/$tfile "(10)"
31479
31480         $TRUNCATE $DIR/$tfile 1234
31481         check_lsom_size $DIR/$tfile 1234 "(11)"
31482         # sync blocks on the MDT
31483         $MULTIOP $DIR/$tfile oc
31484         check_lsom_data $DIR/$tfile "(12)"
31485 }
31486 run_test 806 "Verify Lazy Size on MDS"
31487
31488 test_807() {
31489         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31490         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31491                 skip "Need MDS version at least 2.11.52"
31492
31493         # Registration step
31494         changelog_register || error "changelog_register failed"
31495         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31496         changelog_users $SINGLEMDS | grep -q $cl_user ||
31497                 error "User $cl_user not found in changelog_users"
31498
31499         rm -rf $DIR/$tdir || error "rm $tdir failed"
31500         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31501         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31502         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31503         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31504                 error "truncate $tdir/trunc failed"
31505
31506         local bs=1048576
31507         echo "Test SOM for single-threaded write with fsync"
31508         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31509                 error "write $tfile failed"
31510         sync;sync;sync
31511
31512         # multi-client wirtes
31513         local num=$(get_node_count ${CLIENTS//,/ })
31514         local offset=0
31515         local i=0
31516
31517         echo "Test SOM for multi-client ($num) writes"
31518         touch $DIR/$tfile || error "touch $tfile failed"
31519         $TRUNCATE $DIR/$tfile 0
31520         for client in ${CLIENTS//,/ }; do
31521                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31522                 local pids[$i]=$!
31523                 i=$((i + 1))
31524                 offset=$((offset + $bs))
31525         done
31526         for (( i=0; i < $num; i++ )); do
31527                 wait ${pids[$i]}
31528         done
31529
31530         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31531         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31532         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31533         check_lsom_data $DIR/$tdir/trunc "(0)"
31534         check_lsom_data $DIR/$tdir/single_dd "(1)"
31535         check_lsom_data $DIR/$tfile "(2)"
31536
31537         rm -rf $DIR/$tdir
31538         # Deregistration step
31539         changelog_deregister || error "changelog_deregister failed"
31540 }
31541 run_test 807 "verify LSOM syncing tool"
31542
31543 check_som_nologged()
31544 {
31545         local lines=$($LFS changelog $FSNAME-MDT0000 |
31546                 grep 'x=trusted.som' | wc -l)
31547         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31548 }
31549
31550 test_808() {
31551         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31552                 skip "Need MDS version at least 2.11.55"
31553
31554         # Registration step
31555         changelog_register || error "changelog_register failed"
31556
31557         touch $DIR/$tfile || error "touch $tfile failed"
31558         check_som_nologged
31559
31560         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31561                 error "write $tfile failed"
31562         check_som_nologged
31563
31564         $TRUNCATE $DIR/$tfile 1234
31565         check_som_nologged
31566
31567         $TRUNCATE $DIR/$tfile 1048576
31568         check_som_nologged
31569
31570         # Deregistration step
31571         changelog_deregister || error "changelog_deregister failed"
31572 }
31573 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31574
31575 check_som_nodata()
31576 {
31577         $LFS getsom $1
31578         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31579 }
31580
31581 test_809() {
31582         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31583                 skip "Need MDS version at least 2.11.56"
31584
31585         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31586                 error "failed to create DoM-only file $DIR/$tfile"
31587         touch $DIR/$tfile || error "touch $tfile failed"
31588         check_som_nodata $DIR/$tfile
31589
31590         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31591                 error "write $tfile failed"
31592         check_som_nodata $DIR/$tfile
31593
31594         $TRUNCATE $DIR/$tfile 1234
31595         check_som_nodata $DIR/$tfile
31596
31597         $TRUNCATE $DIR/$tfile 4097
31598         check_som_nodata $DIR/$file
31599 }
31600 run_test 809 "Verify no SOM xattr store for DoM-only files"
31601
31602 test_810() {
31603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31604         $GSS && skip_env "could not run with gss"
31605         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31606                 skip "OST < 2.12.58 doesn't align checksum"
31607
31608         set_checksums 1
31609         stack_trap "set_checksums $ORIG_CSUM" EXIT
31610         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31611
31612         local csum
31613         local before
31614         local after
31615         for csum in $CKSUM_TYPES; do
31616                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31617                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31618                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31619                         eval set -- $i
31620                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31621                         before=$(md5sum $DIR/$tfile)
31622                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31623                         after=$(md5sum $DIR/$tfile)
31624                         [ "$before" == "$after" ] ||
31625                                 error "$csum: $before != $after bs=$1 seek=$2"
31626                 done
31627         done
31628 }
31629 run_test 810 "partial page writes on ZFS (LU-11663)"
31630
31631 test_812a() {
31632         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31633                 skip "OST < 2.12.51 doesn't support this fail_loc"
31634         local old
31635
31636         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31637         $LCTL set_param osc.*.idle_timeout=10
31638         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31639
31640         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31641         # ensure ost1 is connected
31642         stat $DIR/$tfile >/dev/null || error "can't stat"
31643         wait_osc_import_state client ost1 FULL
31644         # no locks, no reqs to let the connection idle
31645         cancel_lru_locks osc
31646
31647         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31648 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31649         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31650         wait_osc_import_state client ost1 CONNECTING
31651         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31652
31653         stat $DIR/$tfile >/dev/null || error "can't stat file"
31654 }
31655 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31656
31657 test_812b() { # LU-12378
31658         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31659                 skip "OST < 2.12.51 doesn't support this fail_loc"
31660         local old
31661
31662         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31663         $LCTL set_param osc.*.idle_timeout=10
31664         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31665
31666         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31667         # ensure ost1 is connected
31668         stat $DIR/$tfile >/dev/null || error "can't stat"
31669         wait_osc_import_state client ost1 FULL
31670         # no locks, no reqs to let the connection idle
31671         cancel_lru_locks osc
31672
31673         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31674 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31675         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31676         wait_osc_import_state client ost1 CONNECTING
31677         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31678
31679         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31680         wait_osc_import_state client ost1 IDLE
31681 }
31682 run_test 812b "do not drop no resend request for idle connect"
31683
31684 test_812c() {
31685         local old
31686
31687         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31688
31689         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31690         $LFS getstripe $DIR/$tfile
31691         $LCTL set_param osc.*.idle_timeout=10
31692         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31693         # ensure ost1 is connected
31694         stat $DIR/$tfile >/dev/null || error "can't stat"
31695         wait_osc_import_state client ost1 FULL
31696         # no locks, no reqs to let the connection idle
31697         cancel_lru_locks osc
31698
31699 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31700         $LCTL set_param fail_loc=0x80000533
31701         sleep 15
31702         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31703 }
31704 run_test 812c "idle import vs lock enqueue race"
31705
31706 test_813() {
31707         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31708         [ -z "$file_heat_sav" ] && skip "no file heat support"
31709
31710         local readsample
31711         local writesample
31712         local readbyte
31713         local writebyte
31714         local readsample1
31715         local writesample1
31716         local readbyte1
31717         local writebyte1
31718
31719         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31720         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31721
31722         $LCTL set_param -n llite.*.file_heat=1
31723         echo "Turn on file heat"
31724         echo "Period second: $period_second, Decay percentage: $decay_pct"
31725
31726         echo "QQQQ" > $DIR/$tfile
31727         echo "QQQQ" > $DIR/$tfile
31728         echo "QQQQ" > $DIR/$tfile
31729         cat $DIR/$tfile > /dev/null
31730         cat $DIR/$tfile > /dev/null
31731         cat $DIR/$tfile > /dev/null
31732         cat $DIR/$tfile > /dev/null
31733
31734         local out=$($LFS heat_get $DIR/$tfile)
31735
31736         $LFS heat_get $DIR/$tfile
31737         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31738         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31739         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31740         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31741
31742         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31743         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31744         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31745         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31746
31747         sleep $((period_second + 3))
31748         echo "Sleep $((period_second + 3)) seconds..."
31749         # The recursion formula to calculate the heat of the file f is as
31750         # follow:
31751         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31752         # Where Hi is the heat value in the period between time points i*I and
31753         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31754         # to the weight of Ci.
31755         out=$($LFS heat_get $DIR/$tfile)
31756         $LFS heat_get $DIR/$tfile
31757         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31758         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31759         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31760         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31761
31762         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31763                 error "read sample ($readsample) is wrong"
31764         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31765                 error "write sample ($writesample) is wrong"
31766         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31767                 error "read bytes ($readbyte) is wrong"
31768         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31769                 error "write bytes ($writebyte) is wrong"
31770
31771         echo "QQQQ" > $DIR/$tfile
31772         echo "QQQQ" > $DIR/$tfile
31773         echo "QQQQ" > $DIR/$tfile
31774         cat $DIR/$tfile > /dev/null
31775         cat $DIR/$tfile > /dev/null
31776         cat $DIR/$tfile > /dev/null
31777         cat $DIR/$tfile > /dev/null
31778
31779         sleep $((period_second + 3))
31780         echo "Sleep $((period_second + 3)) seconds..."
31781
31782         out=$($LFS heat_get $DIR/$tfile)
31783         $LFS heat_get $DIR/$tfile
31784         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31785         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31786         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31787         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31788
31789         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31790                 4 * $decay_pct) / 100") -eq 1 ] ||
31791                 error "read sample ($readsample1) is wrong"
31792         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31793                 3 * $decay_pct) / 100") -eq 1 ] ||
31794                 error "write sample ($writesample1) is wrong"
31795         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31796                 20 * $decay_pct) / 100") -eq 1 ] ||
31797                 error "read bytes ($readbyte1) is wrong"
31798         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31799                 15 * $decay_pct) / 100") -eq 1 ] ||
31800                 error "write bytes ($writebyte1) is wrong"
31801
31802         echo "Turn off file heat for the file $DIR/$tfile"
31803         $LFS heat_set -o $DIR/$tfile
31804
31805         echo "QQQQ" > $DIR/$tfile
31806         echo "QQQQ" > $DIR/$tfile
31807         echo "QQQQ" > $DIR/$tfile
31808         cat $DIR/$tfile > /dev/null
31809         cat $DIR/$tfile > /dev/null
31810         cat $DIR/$tfile > /dev/null
31811         cat $DIR/$tfile > /dev/null
31812
31813         out=$($LFS heat_get $DIR/$tfile)
31814         $LFS heat_get $DIR/$tfile
31815         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31816         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31817         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31818         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31819
31820         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31821         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31822         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31823         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31824
31825         echo "Trun on file heat for the file $DIR/$tfile"
31826         $LFS heat_set -O $DIR/$tfile
31827
31828         echo "QQQQ" > $DIR/$tfile
31829         echo "QQQQ" > $DIR/$tfile
31830         echo "QQQQ" > $DIR/$tfile
31831         cat $DIR/$tfile > /dev/null
31832         cat $DIR/$tfile > /dev/null
31833         cat $DIR/$tfile > /dev/null
31834         cat $DIR/$tfile > /dev/null
31835
31836         out=$($LFS heat_get $DIR/$tfile)
31837         $LFS heat_get $DIR/$tfile
31838         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31839         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31840         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31841         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31842
31843         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31844         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31845         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31846         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31847
31848         $LFS heat_set -c $DIR/$tfile
31849         $LCTL set_param -n llite.*.file_heat=0
31850         echo "Turn off file heat support for the Lustre filesystem"
31851
31852         echo "QQQQ" > $DIR/$tfile
31853         echo "QQQQ" > $DIR/$tfile
31854         echo "QQQQ" > $DIR/$tfile
31855         cat $DIR/$tfile > /dev/null
31856         cat $DIR/$tfile > /dev/null
31857         cat $DIR/$tfile > /dev/null
31858         cat $DIR/$tfile > /dev/null
31859
31860         out=$($LFS heat_get $DIR/$tfile)
31861         $LFS heat_get $DIR/$tfile
31862         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31863         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31864         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31865         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31866
31867         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31868         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31869         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31870         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31871
31872         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31873         rm -f $DIR/$tfile
31874 }
31875 run_test 813 "File heat verfication"
31876
31877 test_814()
31878 {
31879         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31880         echo -n y >> $DIR/$tfile
31881         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31882         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31883 }
31884 run_test 814 "sparse cp works as expected (LU-12361)"
31885
31886 test_815()
31887 {
31888         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31889         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31890 }
31891 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31892
31893 test_816() {
31894         local ost1_imp=$(get_osc_import_name client ost1)
31895         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31896                          cut -d'.' -f2)
31897         local old
31898
31899         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31900         $LCTL set_param osc.*.idle_timeout=10
31901         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31902
31903         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31904         # ensure ost1 is connected
31905
31906         stat $DIR/$tfile >/dev/null || error "can't stat"
31907         wait_osc_import_state client ost1 FULL
31908         # no locks, no reqs to let the connection idle
31909         cancel_lru_locks osc
31910         lru_resize_disable osc
31911         local before
31912         local now
31913         before=$($LCTL get_param -n \
31914                  ldlm.namespaces.$imp_name.lru_size)
31915
31916         wait_osc_import_state client ost1 IDLE
31917         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31918         now=$($LCTL get_param -n \
31919               ldlm.namespaces.$imp_name.lru_size)
31920         [ $before == $now ] || error "lru_size changed $before != $now"
31921 }
31922 run_test 816 "do not reset lru_resize on idle reconnect"
31923
31924 cleanup_817() {
31925         umount $tmpdir
31926         exportfs -u localhost:$DIR/nfsexp
31927         rm -rf $DIR/nfsexp
31928 }
31929
31930 test_817() {
31931         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31932
31933         mkdir -p $DIR/nfsexp
31934         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31935                 error "failed to export nfs"
31936
31937         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31938         stack_trap cleanup_817 EXIT
31939
31940         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31941                 error "failed to mount nfs to $tmpdir"
31942
31943         cp /bin/true $tmpdir
31944         $DIR/nfsexp/true || error "failed to execute 'true' command"
31945 }
31946 run_test 817 "nfsd won't cache write lock for exec file"
31947
31948 test_818() {
31949         test_mkdir -i0 -c1 $DIR/$tdir
31950         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31951         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31952         stop $SINGLEMDS
31953
31954         # restore osp-syn threads
31955         stack_trap "fail $SINGLEMDS"
31956
31957         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31958         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31959         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31960                 error "start $SINGLEMDS failed"
31961         rm -rf $DIR/$tdir
31962
31963         local testid=$(echo $TESTNAME | tr '_' ' ')
31964
31965         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31966                 grep "run LFSCK" || error "run LFSCK is not suggested"
31967 }
31968 run_test 818 "unlink with failed llog"
31969
31970 test_819a() {
31971         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31972         cancel_lru_locks osc
31973         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31974         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31975         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31976         rm -f $TDIR/$tfile
31977 }
31978 run_test 819a "too big niobuf in read"
31979
31980 test_819b() {
31981         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31982         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31983         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31984         cancel_lru_locks osc
31985         sleep 1
31986         rm -f $TDIR/$tfile
31987 }
31988 run_test 819b "too big niobuf in write"
31989
31990
31991 function test_820_start_ost() {
31992         sleep 5
31993
31994         for num in $(seq $OSTCOUNT); do
31995                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31996         done
31997 }
31998
31999 test_820() {
32000         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
32001
32002         mkdir $DIR/$tdir
32003         umount_client $MOUNT || error "umount failed"
32004         for num in $(seq $OSTCOUNT); do
32005                 stop ost$num
32006         done
32007
32008         # mount client with no active OSTs
32009         # so that the client can't initialize max LOV EA size
32010         # from OSC notifications
32011         mount_client $MOUNT || error "mount failed"
32012         # delay OST starting to keep this 0 max EA size for a while
32013         test_820_start_ost &
32014
32015         # create a directory on MDS2
32016         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
32017                 error "Failed to create directory"
32018         # open intent should update default EA size
32019         # see mdc_update_max_ea_from_body()
32020         # notice this is the very first RPC to MDS2
32021         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
32022         ret=$?
32023         echo $out
32024         # With SSK, this situation can lead to -EPERM being returned.
32025         # In that case, simply retry.
32026         if [ $ret -ne 0 ] && $SHARED_KEY; then
32027                 if echo "$out" | grep -q "not permitted"; then
32028                         cp /etc/services $DIR/$tdir/mds2
32029                         ret=$?
32030                 fi
32031         fi
32032         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
32033 }
32034 run_test 820 "update max EA from open intent"
32035
32036 test_823() {
32037         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
32038         local OST_MAX_PRECREATE=20000
32039
32040         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
32041                 skip "Need MDS version at least 2.14.56"
32042
32043         save_lustre_params mds1 \
32044                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
32045         do_facet $SINGLEMDS "$LCTL set_param -n \
32046                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
32047         do_facet $SINGLEMDS "$LCTL set_param -n \
32048                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
32049
32050         stack_trap "restore_lustre_params < $p; rm $p"
32051
32052         do_facet $SINGLEMDS "$LCTL set_param -n \
32053                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
32054
32055         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
32056                       osp.$FSNAME-OST0000*MDT0000.create_count")
32057         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
32058                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
32059         local expect_count=$(((($max/2)/256) * 256))
32060
32061         log "setting create_count to 100200:"
32062         log " -result- count: $count with max: $max, expecting: $expect_count"
32063
32064         [[ $count -eq expect_count ]] ||
32065                 error "Create count not set to max precreate."
32066 }
32067 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
32068
32069 test_831() {
32070         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
32071                 skip "Need MDS version 2.14.56"
32072
32073         local sync_changes=$(do_facet $SINGLEMDS \
32074                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32075
32076         [ "$sync_changes" -gt 100 ] &&
32077                 skip "Sync changes $sync_changes > 100 already"
32078
32079         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
32080
32081         $LFS mkdir -i 0 $DIR/$tdir
32082         $LFS setstripe -c 1 -i 0 $DIR/$tdir
32083
32084         save_lustre_params mds1 \
32085                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
32086         save_lustre_params mds1 \
32087                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
32088
32089         do_facet mds1 "$LCTL set_param -n \
32090                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
32091                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
32092         stack_trap "restore_lustre_params < $p" EXIT
32093
32094         createmany -o $DIR/$tdir/f- 1000
32095         unlinkmany $DIR/$tdir/f- 1000 &
32096         local UNLINK_PID=$!
32097
32098         while sleep 1; do
32099                 sync_changes=$(do_facet mds1 \
32100                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32101                 # the check in the code is racy, fail the test
32102                 # if the value above the limit by 10.
32103                 [ $sync_changes -gt 110 ] && {
32104                         kill -2 $UNLINK_PID
32105                         wait
32106                         error "osp changes throttling failed, $sync_changes>110"
32107                 }
32108                 kill -0 $UNLINK_PID 2> /dev/null || break
32109         done
32110         wait
32111 }
32112 run_test 831 "throttling unlink/setattr queuing on OSP"
32113
32114 test_832() {
32115         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32116         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
32117                 skip "Need MDS version 2.15.52+"
32118         is_rmentry_supported || skip "rm_entry not supported"
32119
32120         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
32121         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
32122         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
32123                 error "mkdir remote_dir failed"
32124         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
32125                 error "mkdir striped_dir failed"
32126         touch $DIR/$tdir/file || error "touch file failed"
32127         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
32128         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
32129 }
32130 run_test 832 "lfs rm_entry"
32131
32132 test_833() {
32133         local file=$DIR/$tfile
32134
32135         stack_trap "rm -f $file" EXIT
32136         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
32137
32138         local wpid
32139         local rpid
32140         local rpid2
32141
32142         # Buffered I/O write
32143         (
32144                 while [ ! -e $DIR/sanity.833.lck ]; do
32145                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
32146                                 error "failed to write $file"
32147                         sleep 0.$((RANDOM % 4 + 1))
32148                 done
32149         )&
32150         wpid=$!
32151
32152         # Buffered I/O read
32153         (
32154                 while [ ! -e $DIR/sanity.833.lck ]; do
32155                         dd if=$file of=/dev/null bs=1M count=50 ||
32156                                 error "failed to read $file"
32157                         sleep 0.$((RANDOM % 4 + 1))
32158                 done
32159         )&
32160         rpid=$!
32161
32162         # Direct I/O read
32163         (
32164                 while [ ! -e $DIR/sanity.833.lck ]; do
32165                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32166                                 error "failed to read $file in direct I/O mode"
32167                         sleep 0.$((RANDOM % 4 + 1))
32168                 done
32169         )&
32170         rpid2=$!
32171
32172         sleep 30
32173         touch $DIR/sanity.833.lck
32174         wait $wpid || error "$?: buffered write failed"
32175         wait $rpid || error "$?: buffered read failed"
32176         wait $rpid2 || error "$?: direct read failed"
32177 }
32178 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32179
32180 test_842() {
32181         local oss1=$(facet_host ost1)
32182
32183         # Try to insert the module.  This will leave results in dmesg
32184         now=$(date +%s)
32185         log "STAMP $now" > /dev/kmsg
32186         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32187                 error "$oss1 load_module ldlm_extent failed"
32188
32189         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32190         do_node $oss1 rmmod -v ldlm_extent ||
32191                 error "rmmod failed (may trigger a failure in a later test)"
32192 }
32193 run_test 842 "Measure ldlm_extent performance"
32194
32195 test_850() {
32196         local dir=$DIR/$tdir
32197         local file=$dir/$tfile
32198         local statsfile=$dir/all_job_stats.txt
32199
32200         test_mkdir -p $dir || error "failed to create dir $dir"
32201         echo "abcdefg" > $file || error "failed to create file $file"
32202
32203         # read job_stats in the living system
32204         lljobstat -n 1 ||
32205                 error "failed to run lljobstat on living system"
32206
32207         $LCTL get_param *.*.job_stats > $statsfile
32208         lljobstat --statsfile=$statsfile ||
32209                 error "failed to run lljobstat on file $statsfile"
32210 }
32211 run_test 850 "lljobstat can parse living and aggregated job_stats"
32212
32213 test_851() {
32214         local dir=$DIR/$tdir
32215         local file=$dir/f_test_851_$$
32216         local report=/tmp/report_test_851_$$
32217         local fanotify_prog=monitor_lustrefs
32218         local pid
32219
32220         test_mkdir $dir || error "failed to create dir $dir"
32221
32222         $fanotify_prog $DIR > $report &
32223         pid=$!
32224
32225         sleep 1
32226         if ! kill -0 $pid; then
32227                 error "failed to start $fanoify_prog"
32228         fi
32229
32230         stack_trap "kill $pid"
32231         stack_trap "rm -f $report"
32232
32233         echo "1234567890" > $file
32234         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32235                 error "fanotify did not report anything after 30 seconds"
32236         grep -a -E "open.*:$file:" $report ||
32237                 error "no open event for writing $file"
32238         grep -a -E "write.*:$file:" $report ||
32239                 error "no write event for writing $file"
32240         grep -a -E "close.*:$file:" $report ||
32241                 error "no close event for writing $file"
32242
32243         > $report
32244         cat $file
32245         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32246                 error "fanotify did not report anything after 30 seconds"
32247         grep -a -E "open.*:$file:" $report ||
32248                 error "no open event for reading $file"
32249         grep -a -E "read.*:$file:" $report ||
32250                 error "no write event for reading $file"
32251         grep -a -E "close.*:$file:" $report ||
32252                 error "no close event for reading $file"
32253 }
32254 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32255
32256 test_852() {
32257         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32258         (( $MDS1_VERSION >= $(version_code 2.15.61) )) ||
32259                 skip "Need MDS version at least 2.15.61 for intent mkdir"
32260
32261         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
32262
32263         save_lustre_params client "llite.*.intent_mkdir" > $save
32264         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
32265         $LCTL set_param llite.*.intent_mkdir=1
32266
32267         test_mkdir -p -c$MDSCOUNT $DIR/$tdir
32268         if [ $MDSCOUNT -ge 2 ]; then
32269                 $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir ||
32270                         error "set default dirstripe failed"
32271         fi
32272
32273         mkdir $DIR/$tdir/tdir || error "mkdir tdir failed"
32274         mkdir $DIR/$tdir/tdir/tfile || error "mkdir tdir/tfile failed"
32275         touch -d "2020-08-25 15:08" $DIR/$tdir/tdir/tfile ||
32276                 error "touch time failed"
32277         chown 0:0 $DIR/$tdir/tdir/tfile || error "chown 0:0 tdir/tfile failed"
32278         chmod 755 $DIR/$tdir/tdir/tfile || error "chmod 755 tdir/tfile failed"
32279 }
32280 run_test 852 "mkdir using intent lock for striped directory"
32281
32282 #
32283 # tests that do cleanup/setup should be run at the end
32284 #
32285
32286 test_900() {
32287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32288         local ls
32289
32290         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32291         $LCTL set_param fail_loc=0x903
32292
32293         cancel_lru_locks MGC
32294
32295         FAIL_ON_ERROR=true cleanup
32296         FAIL_ON_ERROR=true setup
32297 }
32298 run_test 900 "umount should not race with any mgc requeue thread"
32299
32300 # LUS-6253/LU-11185
32301 test_901() {
32302         local old
32303         local count
32304         local oldc
32305         local newc
32306         local olds
32307         local news
32308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32309
32310         # some get_param have a bug to handle dot in param name
32311         cancel_lru_locks MGC
32312         old=$(mount -t lustre | wc -l)
32313         # 1 config+sptlrpc
32314         # 2 params
32315         # 3 nodemap
32316         # 4 IR
32317         old=$((old * 4))
32318         oldc=0
32319         count=0
32320         while [ $old -ne $oldc ]; do
32321                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32322                 sleep 1
32323                 ((count++))
32324                 if [ $count -ge $TIMEOUT ]; then
32325                         error "too large timeout"
32326                 fi
32327         done
32328         umount_client $MOUNT || error "umount failed"
32329         mount_client $MOUNT || error "mount failed"
32330         cancel_lru_locks MGC
32331         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32332
32333         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32334
32335         return 0
32336 }
32337 run_test 901 "don't leak a mgc lock on client umount"
32338
32339 # LU-13377
32340 test_902() {
32341         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32342                 skip "client does not have LU-13377 fix"
32343         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32344         $LCTL set_param fail_loc=0x1415
32345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32346         cancel_lru_locks osc
32347         rm -f $DIR/$tfile
32348 }
32349 run_test 902 "test short write doesn't hang lustre"
32350
32351 # LU-14711
32352 test_903() {
32353         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32354         echo "blah" > $DIR/${tfile}-2
32355         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32356         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32357         $LCTL set_param fail_loc=0x417 fail_val=20
32358
32359         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32360         sleep 1 # To start the destroy
32361         wait_destroy_complete 150 || error "Destroy taking too long"
32362         cat $DIR/$tfile > /dev/null || error "Evicted"
32363 }
32364 run_test 903 "Test long page discard does not cause evictions"
32365
32366 test_904() {
32367         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32368         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32369                 grep -q project || skip "skip project quota not supported"
32370
32371         local testfile="$DIR/$tdir/$tfile"
32372         local xattr="trusted.projid"
32373         local projid
32374         local mdts=$(comma_list $(mdts_nodes))
32375         local saved=$(do_facet mds1 $LCTL get_param -n \
32376                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32377
32378         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32379         stack_trap "do_nodes $mdts $LCTL set_param \
32380                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32381
32382         mkdir -p $DIR/$tdir
32383         touch $testfile
32384         #hide projid xattr on server
32385         $LFS project -p 1 $testfile ||
32386                 error "set $testfile project id failed"
32387         getfattr -m - $testfile | grep $xattr &&
32388                 error "do not show trusted.projid when disabled on server"
32389         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32390         #should be hidden when projid is 0
32391         $LFS project -p 0 $testfile ||
32392                 error "set $testfile project id failed"
32393         getfattr -m - $testfile | grep $xattr &&
32394                 error "do not show trusted.projid with project ID 0"
32395
32396         #still can getxattr explicitly
32397         projid=$(getfattr -n $xattr $testfile |
32398                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32399         [ $projid == "0" ] ||
32400                 error "projid expected 0 not $projid"
32401
32402         #set the projid via setxattr
32403         setfattr -n $xattr -v "1000" $testfile ||
32404                 error "setattr failed with $?"
32405         projid=($($LFS project $testfile))
32406         [ ${projid[0]} == "1000" ] ||
32407                 error "projid expected 1000 not $projid"
32408
32409         #check the new projid via getxattr
32410         $LFS project -p 1001 $testfile ||
32411                 error "set $testfile project id failed"
32412         getfattr -m - $testfile | grep $xattr ||
32413                 error "should show trusted.projid when project ID != 0"
32414         projid=$(getfattr -n $xattr $testfile |
32415                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32416         [ $projid == "1001" ] ||
32417                 error "projid expected 1001 not $projid"
32418
32419         #try to set invalid projid
32420         setfattr -n $xattr -v "4294967295" $testfile &&
32421                 error "set invalid projid should fail"
32422
32423         #remove the xattr means setting projid to 0
32424         setfattr -x $xattr $testfile ||
32425                 error "setfattr failed with $?"
32426         projid=($($LFS project $testfile))
32427         [ ${projid[0]} == "0" ] ||
32428                 error "projid expected 0 not $projid"
32429
32430         #should be hidden when parent has inherit flag and same projid
32431         $LFS project -srp 1002 $DIR/$tdir ||
32432                 error "set $tdir project id failed"
32433         getfattr -m - $testfile | grep $xattr &&
32434                 error "do not show trusted.projid with inherit flag"
32435
32436         #still can getxattr explicitly
32437         projid=$(getfattr -n $xattr $testfile |
32438                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32439         [ $projid == "1002" ] ||
32440                 error "projid expected 1002 not $projid"
32441 }
32442 run_test 904 "virtual project ID xattr"
32443
32444 # LU-8582
32445 test_905() {
32446         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32447                 skip "need OST version >= 2.15.50.220 for fail_loc"
32448
32449         remote_ost_nodsh && skip "remote OST with nodsh"
32450         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32451
32452         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32453
32454         #define OBD_FAIL_OST_OPCODE 0x253
32455         # OST_LADVISE = 21
32456         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32457         $LFS ladvise -a willread $DIR/$tfile &&
32458                 error "unexpected success of ladvise with fault injection"
32459         $LFS ladvise -a willread $DIR/$tfile |&
32460                 grep -q "Operation not supported"
32461         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32462 }
32463 run_test 905 "bad or new opcode should not stuck client"
32464
32465 test_906() {
32466         grep -q io_uring_setup /proc/kallsyms ||
32467                 skip "Client OS does not support io_uring I/O engine"
32468         io_uring_probe || skip "kernel does not support io_uring fully"
32469         which fio || skip_env "no fio installed"
32470         fio --enghelp | grep -q io_uring ||
32471                 skip_env "fio does not support io_uring I/O engine"
32472
32473         local file=$DIR/$tfile
32474         local ioengine="io_uring"
32475         local numjobs=2
32476         local size=50M
32477
32478         fio --name=seqwrite --ioengine=$ioengine        \
32479                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32480                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32481                 error "fio seqwrite $file failed"
32482
32483         fio --name=seqread --ioengine=$ioengine \
32484                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32485                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32486                 error "fio seqread $file failed"
32487
32488         rm -f $file || error "rm -f $file failed"
32489 }
32490 run_test 906 "Simple test for io_uring I/O engine via fio"
32491
32492 test_907() {
32493         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32494
32495         # set stripe size to max rpc size
32496         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32497         $LFS getstripe $DIR/$tfile
32498 #define OBD_FAIL_OST_EROFS               0x216
32499         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32500
32501         local bs=$((max_pages * PAGE_SIZE / 16))
32502
32503         # write full one stripe and one block
32504         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32505
32506         rm $DIR/$tfile || error "rm failed"
32507 }
32508 run_test 907 "write rpc error during unlink"
32509
32510 complete_test $SECONDS
32511 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32512 check_and_cleanup_lustre
32513 if [ "$I_MOUNTED" != "yes" ]; then
32514         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32515 fi
32516 exit_status