Whamcloud - gitweb
LU-17662 osd-zfs: Support for ZFS 2.2.3
[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_27Ia() {
2816         (( $MDS1_VERSION >= $(version_code 2.15.61.225) )) ||
2817                 skip "need MDS >= 2.15.61.255 for pool inheritance fix"
2818
2819         (( $OSTCOUNT >= 2 )) || skip_env "needs >= 2 OSTs"
2820
2821         save_layout_restore_at_exit $MOUNT
2822         pool_add $TESTNAME || error "pool_add failed"
2823         pool_add_targets $TESTNAME 1 || error "pool_add_targets failed"
2824
2825         $LFS setstripe -p $TESTNAME $MOUNT
2826
2827         test_mkdir $DIR/$tdir
2828         $LFS setstripe -i0 $DIR/$tdir
2829         $MULTIOP $DIR/$tdir/$tfile.1 Oc || error_noexit "multiop failed"
2830         $LFS getstripe $DIR/$tdir/$tfile.1
2831
2832         $LFS setstripe -d $DIR/$tdir
2833         $LFS setstripe -o 0,1 $DIR/$tdir
2834         $MULTIOP $DIR/$tdir/$tfile.2 Oc || error_noexit "multiop failed"
2835         $LFS getstripe $DIR/$tdir/$tfile.2
2836
2837         test_mkdir $DIR/$tdir/d1
2838         $MULTIOP $DIR/$tdir/d1/$tfile.3 Oc || error_noexit "multiop failed"
2839         $LFS getstripe $DIR/$tdir/d1/$tfile.3
2840
2841         $LFS setstripe -d $DIR/$tdir
2842         $LFS setstripe -E 128G -o 0,1 -E-1 $DIR/$tdir
2843         test_mkdir $DIR/$tdir/d2
2844         $MULTIOP $DIR/$tdir/d2/$tfile.4 Oc || error_noexit "multiop failed"
2845         $LFS getstripe $DIR/$tdir/d2/$tfile.4
2846 }
2847 run_test 27Ia "check that root dir pool is dropped with conflict parent dir settings"
2848
2849 test_27J() {
2850         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2851                 skip "Need MDS version newer than 2.12.51"
2852
2853         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2854         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2855         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2856            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2857                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2858
2859         test_mkdir $DIR/$tdir
2860         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2861         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2862
2863         # create foreign file (raw way)
2864         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2865                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2866
2867         ! $LFS setstripe --foreign --flags foo \
2868                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2869                         error "creating $tfile with '--flags foo' should fail"
2870
2871         ! $LFS setstripe --foreign --flags 0xffffffff \
2872                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2873                         error "creating $tfile w/ 0xffffffff flags should fail"
2874
2875         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2876                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2877
2878         # verify foreign file (raw way)
2879         parse_foreign_file -f $DIR/$tdir/$tfile |
2880                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2881                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2882         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2883                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2884         parse_foreign_file -f $DIR/$tdir/$tfile |
2885                 grep "lov_foreign_size: 73" ||
2886                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2887         parse_foreign_file -f $DIR/$tdir/$tfile |
2888                 grep "lov_foreign_type: 1" ||
2889                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2890         parse_foreign_file -f $DIR/$tdir/$tfile |
2891                 grep "lov_foreign_flags: 0x0000DA08" ||
2892                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2893         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2894                 grep "lov_foreign_value: 0x" |
2895                 sed -e 's/lov_foreign_value: 0x//')
2896         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2897         [[ $lov = ${lov2// /} ]] ||
2898                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2899
2900         # create foreign file (lfs + API)
2901         $LFS setstripe --foreign=none --flags 0xda08 \
2902                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2903                 error "$DIR/$tdir/${tfile}2: create failed"
2904
2905         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2906                 grep "lfm_magic:.*0x0BD70BD0" ||
2907                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2908         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2909         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2910                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2911         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2912                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2913         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2914                 grep "lfm_flags:.*0x0000DA08" ||
2915                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2916         $LFS getstripe $DIR/$tdir/${tfile}2 |
2917                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2918                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2919
2920         # modify striping should fail
2921         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2922                 error "$DIR/$tdir/$tfile: setstripe should fail"
2923         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2924                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2925
2926         # R/W should fail
2927         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2928         cat $DIR/$tdir/${tfile}2 &&
2929                 error "$DIR/$tdir/${tfile}2: read should fail"
2930         cat /etc/passwd > $DIR/$tdir/$tfile &&
2931                 error "$DIR/$tdir/$tfile: write should fail"
2932         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2933                 error "$DIR/$tdir/${tfile}2: write should fail"
2934
2935         # chmod should work
2936         chmod 222 $DIR/$tdir/$tfile ||
2937                 error "$DIR/$tdir/$tfile: chmod failed"
2938         chmod 222 $DIR/$tdir/${tfile}2 ||
2939                 error "$DIR/$tdir/${tfile}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2943                 error "$DIR/$tdir/$tfile: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2945                 error "$DIR/$tdir/${tfile}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2949                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2950         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2951                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2952
2953         #remove foreign file
2954         rm $DIR/$tdir/${tfile}.new ||
2955                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2956         rm $DIR/$tdir/${tfile}2.new ||
2957                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2958 }
2959 run_test 27J "basic ops on file with foreign LOV"
2960
2961 test_27K() {
2962         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2963                 skip "Need MDS version newer than 2.12.49"
2964
2965         test_mkdir $DIR/$tdir
2966         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2967         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2968
2969         # create foreign dir (raw way)
2970         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2971                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2972
2973         ! $LFS setdirstripe --foreign --flags foo \
2974                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2975                         error "creating $tdir with '--flags foo' should fail"
2976
2977         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2978                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2979                         error "creating $tdir w/ 0xffffffff flags should fail"
2980
2981         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2982                 error "create_foreign_dir FAILED"
2983
2984         # verify foreign dir (raw way)
2985         parse_foreign_dir -d $DIR/$tdir/$tdir |
2986                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2987                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2988         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2989                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2990         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2991                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2992         parse_foreign_dir -d $DIR/$tdir/$tdir |
2993                 grep "lmv_foreign_flags: 55813$" ||
2994                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2995         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2996                 grep "lmv_foreign_value: 0x" |
2997                 sed 's/lmv_foreign_value: 0x//')
2998         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2999                 sed 's/ //g')
3000         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
3001
3002         # create foreign dir (lfs + API)
3003         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
3004                 $DIR/$tdir/${tdir}2 ||
3005                 error "$DIR/$tdir/${tdir}2: create failed"
3006
3007         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
3008
3009         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3010                 grep "lfm_magic:.*0x0CD50CD0" ||
3011                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
3012         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
3013         # - sizeof(lfm_type) - sizeof(lfm_flags)
3014         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
3015                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
3016         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
3017                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
3018         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3019                 grep "lfm_flags:.*0x0000DA05" ||
3020                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
3021         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
3022                 grep "lfm_value.*${uuid1}@${uuid2}" ||
3023                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
3024
3025         # file create in dir should fail
3026         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3027         touch $DIR/$tdir/${tdir}2/$tfile &&
3028                 error "$DIR/${tdir}2: file create should fail"
3029
3030         # chmod should work
3031         chmod 777 $DIR/$tdir/$tdir ||
3032                 error "$DIR/$tdir: chmod failed"
3033         chmod 777 $DIR/$tdir/${tdir}2 ||
3034                 error "$DIR/${tdir}2: chmod failed"
3035
3036         # chown should work
3037         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3038                 error "$DIR/$tdir: chown failed"
3039         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3040                 error "$DIR/${tdir}2: chown failed"
3041
3042         # rename should work
3043         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3044                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3045         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3046                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3047
3048         #remove foreign dir
3049         rmdir $DIR/$tdir/${tdir}.new ||
3050                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3051         rmdir $DIR/$tdir/${tdir}2.new ||
3052                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3053 }
3054 run_test 27K "basic ops on dir with foreign LMV"
3055
3056 test_27L() {
3057         remote_mds_nodsh && skip "remote MDS with nodsh"
3058
3059         local POOL=${POOL:-$TESTNAME}
3060
3061         pool_add $POOL || error "pool_add failed"
3062
3063         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3064                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3065                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3066 }
3067 run_test 27L "lfs pool_list gives correct pool name"
3068
3069 test_27M() {
3070         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3071                 skip "Need MDS version >= than 2.12.57"
3072         remote_mds_nodsh && skip "remote MDS with nodsh"
3073         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3074
3075         # Set default striping on directory
3076         local setcount=4
3077         local stripe_opt
3078         local mdts=$(comma_list $(mdts_nodes))
3079
3080         # if we run against a 2.12 server which lacks overstring support
3081         # then the connect_flag will not report overstriping, even if client
3082         # is 2.14+
3083         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3084                 stripe_opt="-C $setcount"
3085         elif (( $OSTCOUNT >= $setcount )); then
3086                 stripe_opt="-c $setcount"
3087         else
3088                 skip "server does not support overstriping"
3089         fi
3090
3091         test_mkdir $DIR/$tdir
3092
3093         # Validate existing append_* params and ensure restore
3094         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3095         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3096         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3097
3098         # Validate append_pool name length
3099         (( $MDS1_VERSION >= $(version_code 2.15.61) )) &&
3100                 do_nodes $mdts $LCTL \
3101                         set_param mdd.*.append_pool="LOV_MAXPOOLNAME*" &&
3102                         error "Wrong pool name length should report error"
3103
3104         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3105         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3106         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3107
3108         $LFS setstripe $stripe_opt $DIR/$tdir
3109
3110         echo 1 > $DIR/$tdir/${tfile}.1
3111         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3112         (( $count == $setcount )) ||
3113                 error "(1) stripe count $count, should be $setcount"
3114
3115         local appendcount=$orig_count
3116         echo 1 >> $DIR/$tdir/${tfile}.2_append
3117         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3118         (( $count == $appendcount )) ||
3119                 error "(2)stripe count $count, should be $appendcount for append"
3120
3121         # Disable O_APPEND striping, verify it works
3122         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3123
3124         # Should now get the default striping, which is 4
3125         setcount=4
3126         echo 1 >> $DIR/$tdir/${tfile}.3_append
3127         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3128         (( $count == $setcount )) ||
3129                 error "(3) stripe count $count, should be $setcount"
3130
3131         # Try changing the stripe count for append files
3132         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3133
3134         # Append striping is now 2 (directory default is still 4)
3135         appendcount=2
3136         echo 1 >> $DIR/$tdir/${tfile}.4_append
3137         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3138         (( $count == $appendcount )) ||
3139                 error "(4) stripe count $count, should be $appendcount for append"
3140
3141         # Test append stripe count of -1
3142         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3143         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3144                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3145                 touch $DIR/$tdir/$tfile.specific.{1..128}
3146         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3147
3148         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3149         appendcount=$OSTCOUNT
3150         echo 1 >> $DIR/$tdir/${tfile}.5
3151         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3152         (( $count == $appendcount )) ||
3153                 error "(5) stripe count $count, should be $appendcount for append"
3154
3155         # Set append striping back to default of 1
3156         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3157
3158         # Try a new default striping, PFL + DOM
3159         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3160
3161         # Create normal DOM file, DOM returns stripe count == 0
3162         setcount=0
3163         touch $DIR/$tdir/${tfile}.6
3164         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3165         (( $count == $setcount )) ||
3166                 error "(6) stripe count $count, should be $setcount"
3167
3168         # Show
3169         appendcount=1
3170         echo 1 >> $DIR/$tdir/${tfile}.7_append
3171         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3172         (( $count == $appendcount )) ||
3173                 error "(7) stripe count $count, should be $appendcount for append"
3174
3175         # Clean up DOM layout
3176         $LFS setstripe -d $DIR/$tdir
3177
3178         save_layout_restore_at_exit $MOUNT
3179         # Now test that append striping works when layout is from root
3180         $LFS setstripe -c 2 $MOUNT
3181         # Make a special directory for this
3182         mkdir $DIR/${tdir}/${tdir}.2
3183
3184         # Verify for normal file
3185         setcount=2
3186         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3187         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3188         (( $count == $setcount )) ||
3189                 error "(8) stripe count $count, should be $setcount"
3190
3191         appendcount=1
3192         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3193         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3194         (( $count == $appendcount )) ||
3195                 error "(9) stripe count $count, should be $appendcount for append"
3196
3197         # Now test O_APPEND striping with pools
3198         pool_add $TESTNAME || error "pool creation failed"
3199         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3200         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3201
3202         echo 1 >> $DIR/$tdir/${tfile}.10_append
3203
3204         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3205         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3206
3207         # Check that count is still correct
3208         appendcount=1
3209         echo 1 >> $DIR/$tdir/${tfile}.11_append
3210         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3211         (( $count == $appendcount )) ||
3212                 error "(11) stripe count $count, should be $appendcount for append"
3213
3214         # Disable O_APPEND stripe count, verify pool works separately
3215         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3216
3217         echo 1 >> $DIR/$tdir/${tfile}.12_append
3218
3219         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3220         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3221
3222         # Remove pool setting, verify it's not applied
3223         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3224
3225         echo 1 >> $DIR/$tdir/${tfile}.13_append
3226
3227         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3228         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3229 }
3230 run_test 27M "test O_APPEND striping"
3231
3232 test_27N() {
3233         combined_mgs_mds && skip "needs separate MGS/MDT"
3234
3235         pool_add $TESTNAME || error "pool_add failed"
3236         do_facet mgs "$LCTL pool_list $FSNAME" |
3237                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3238                 error "lctl pool_list on MGS failed"
3239 }
3240 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3241
3242 clean_foreign_symlink() {
3243         trap 0
3244         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3245         for i in $DIR/$tdir/* ; do
3246                 $LFS unlink_foreign $i || true
3247         done
3248 }
3249
3250 test_27O() {
3251         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3252                 skip "Need MDS version newer than 2.12.51"
3253
3254         test_mkdir $DIR/$tdir
3255         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3256         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3257
3258         trap clean_foreign_symlink EXIT
3259
3260         # enable foreign_symlink behaviour
3261         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3262
3263         # foreign symlink LOV format is a partial path by default
3264
3265         # create foreign file (lfs + API)
3266         $LFS setstripe --foreign=symlink --flags 0xda05 \
3267                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3268                 error "$DIR/$tdir/${tfile}: create failed"
3269
3270         $LFS getstripe -v $DIR/$tdir/${tfile} |
3271                 grep "lfm_magic:.*0x0BD70BD0" ||
3272                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3273         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3274                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3275         $LFS getstripe -v $DIR/$tdir/${tfile} |
3276                 grep "lfm_flags:.*0x0000DA05" ||
3277                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3278         $LFS getstripe $DIR/$tdir/${tfile} |
3279                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3280                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3281
3282         # modify striping should fail
3283         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3284                 error "$DIR/$tdir/$tfile: setstripe should fail"
3285
3286         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3287         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3288         cat /etc/passwd > $DIR/$tdir/$tfile &&
3289                 error "$DIR/$tdir/$tfile: write should fail"
3290
3291         # rename should succeed
3292         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3293                 error "$DIR/$tdir/$tfile: rename has failed"
3294
3295         #remove foreign_symlink file should fail
3296         rm $DIR/$tdir/${tfile}.new &&
3297                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3298
3299         #test fake symlink
3300         mkdir /tmp/${uuid1} ||
3301                 error "/tmp/${uuid1}: mkdir has failed"
3302         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3303                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3304         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3305         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3306                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3307         #read should succeed now
3308         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3309                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3310         #write should succeed now
3311         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3312                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3313         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3314                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3315         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3316                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3317
3318         #check that getstripe still works
3319         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3320                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3321
3322         # chmod should still succeed
3323         chmod 644 $DIR/$tdir/${tfile}.new ||
3324                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3325
3326         # chown should still succeed
3327         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3328                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3329
3330         # rename should still succeed
3331         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3332                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3333
3334         #remove foreign_symlink file should still fail
3335         rm $DIR/$tdir/${tfile} &&
3336                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3337
3338         #use special ioctl() to unlink foreign_symlink file
3339         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3340                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3341
3342 }
3343 run_test 27O "basic ops on foreign file of symlink type"
3344
3345 test_27P() {
3346         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3347                 skip "Need MDS version newer than 2.12.49"
3348
3349         test_mkdir $DIR/$tdir
3350         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3351         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3352
3353         trap clean_foreign_symlink EXIT
3354
3355         # enable foreign_symlink behaviour
3356         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3357
3358         # foreign symlink LMV format is a partial path by default
3359
3360         # create foreign dir (lfs + API)
3361         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3362                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3363                 error "$DIR/$tdir/${tdir}: create failed"
3364
3365         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3366
3367         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3368                 grep "lfm_magic:.*0x0CD50CD0" ||
3369                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3370         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3371                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3372         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3373                 grep "lfm_flags:.*0x0000DA05" ||
3374                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3375         $LFS getdirstripe $DIR/$tdir/${tdir} |
3376                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3377                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3378
3379         # file create in dir should fail
3380         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3381         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3382
3383         # rename should succeed
3384         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3385                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3386
3387         #remove foreign_symlink dir should fail
3388         rmdir $DIR/$tdir/${tdir}.new &&
3389                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3390
3391         #test fake symlink
3392         mkdir -p /tmp/${uuid1}/${uuid2} ||
3393                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3394         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3395                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3396         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3397         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3398                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3399         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3400                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3401
3402         #check that getstripe fails now that foreign_symlink enabled
3403         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3404                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3405
3406         # file create in dir should work now
3407         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3408                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3409         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3410                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3411         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3412                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3413
3414         # chmod should still succeed
3415         chmod 755 $DIR/$tdir/${tdir}.new ||
3416                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3417
3418         # chown should still succeed
3419         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3420                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3421
3422         # rename should still succeed
3423         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3424                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3425
3426         #remove foreign_symlink dir should still fail
3427         rmdir $DIR/$tdir/${tdir} &&
3428                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3429
3430         #use special ioctl() to unlink foreign_symlink file
3431         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3432                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3433
3434         #created file should still exist
3435         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3436                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3437         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3438                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3439 }
3440 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3441
3442 test_27Q() {
3443         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3444         stack_trap "rm -f $TMP/$tfile*"
3445
3446         test_mkdir $DIR/$tdir-1
3447         test_mkdir $DIR/$tdir-2
3448
3449         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3450         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3451
3452         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3453         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3454
3455         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3456         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3457
3458         # Create some bad symlinks and ensure that we don't loop
3459         # forever or something. These should return ELOOP (40) and
3460         # ENOENT (2) but I don't want to test for that because there's
3461         # always some weirdo architecture that needs to ruin
3462         # everything by defining these error numbers differently.
3463
3464         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3465         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3466
3467         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3468         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3469
3470         return 0
3471 }
3472 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3473
3474 test_27R() {
3475         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3476                 skip "need MDS 2.14.55 or later"
3477         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3478
3479         local testdir="$DIR/$tdir"
3480         test_mkdir -p $testdir
3481         stack_trap "rm -rf $testdir"
3482         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3483
3484         local f1="$testdir/f1"
3485         touch $f1 || error "failed to touch $f1"
3486         local count=$($LFS getstripe -c $f1)
3487         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3488
3489         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3490         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3491
3492         local maxcount=$(($OSTCOUNT - 1))
3493         local mdts=$(comma_list $(mdts_nodes))
3494         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3495         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3496
3497         local f2="$testdir/f2"
3498         touch $f2 || error "failed to touch $f2"
3499         local count=$($LFS getstripe -c $f2)
3500         (( $count == $maxcount )) || error "wrong stripe count"
3501 }
3502 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3503
3504 test_27T() {
3505         [ $(facet_host client) == $(facet_host ost1) ] &&
3506                 skip "need ost1 and client on different nodes"
3507
3508 #define OBD_FAIL_OSC_NO_GRANT            0x411
3509         $LCTL set_param fail_loc=0x20000411 fail_val=1
3510 #define OBD_FAIL_OST_ENOSPC              0x215
3511         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3512         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3513         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3514                 error "multiop failed"
3515 }
3516 run_test 27T "no eio on close on partial write due to enosp"
3517
3518 test_27U() {
3519         local dir=$DIR/$tdir
3520         local file=$dir/$tfile
3521         local append_pool=${TESTNAME}-append
3522         local normal_pool=${TESTNAME}-normal
3523         local pool
3524         local stripe_count
3525         local stripe_count2
3526         local mdts=$(comma_list $(mdts_nodes))
3527
3528         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3529                 skip "Need MDS version at least 2.15.51 for append pool feature"
3530
3531         # Validate existing append_* params and ensure restore
3532         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3533         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3534         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3535
3536         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3537         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3538         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3539
3540         pool_add $append_pool || error "pool creation failed"
3541         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3542
3543         pool_add $normal_pool || error "pool creation failed"
3544         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3545
3546         test_mkdir $dir
3547         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3548
3549         echo XXX >> $file.1
3550         $LFS getstripe $file.1
3551
3552         pool=$($LFS getstripe -p $file.1)
3553         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3554
3555         stripe_count2=$($LFS getstripe -c $file.1)
3556         ((stripe_count2 == stripe_count)) ||
3557                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3558
3559         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3560
3561         echo XXX >> $file.2
3562         $LFS getstripe $file.2
3563
3564         pool=$($LFS getstripe -p $file.2)
3565         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3566
3567         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3568
3569         echo XXX >> $file.3
3570         $LFS getstripe $file.3
3571
3572         stripe_count2=$($LFS getstripe -c $file.3)
3573         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3574 }
3575 run_test 27U "append pool and stripe count work with composite default layout"
3576
3577 test_27V() {
3578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3579         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3580
3581         local dir=$DIR/$tdir
3582         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3583         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3584         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3585         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3586         local pid
3587
3588         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3589
3590         do_facet mds1 $LCTL set_param $lod_param=0
3591         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3592
3593         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3594         stack_trap "rm -rf $dir"
3595
3596         # exercise race in LU-16981 with deactivating OST while creating a file
3597         (
3598                 while true; do
3599                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3600                         sleep 0.1
3601                         do_facet mds1 \
3602                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3603                 done
3604         ) &
3605
3606         pid=$!
3607         stack_trap "kill -9 $pid"
3608
3609         # errors here are OK so ignore them (just don't want to crash)
3610         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3611
3612         return 0
3613 }
3614 run_test 27V "creating widely striped file races with deactivating OST"
3615
3616 # createtest also checks that device nodes are created and
3617 # then visible correctly (#2091)
3618 test_28() { # bug 2091
3619         test_mkdir $DIR/d28
3620         $CREATETEST $DIR/d28/ct || error "createtest failed"
3621 }
3622 run_test 28 "create/mknod/mkdir with bad file types ============"
3623
3624 test_29() {
3625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3626
3627         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3628                 disable_opencache
3629                 stack_trap "restore_opencache"
3630         }
3631
3632         sync; sleep 1; sync # flush out any dirty pages from previous tests
3633         cancel_lru_locks
3634         test_mkdir $DIR/d29
3635         touch $DIR/d29/foo
3636         log 'first d29'
3637         ls -l $DIR/d29
3638
3639         local locks_orig=$(total_used_locks mdc)
3640         (( $locks_orig != 0 )) || error "No mdc lock count"
3641
3642         local locks_unused_orig=$(total_unused_locks mdc)
3643
3644         log 'second d29'
3645         ls -l $DIR/d29
3646         log 'done'
3647
3648         local locks_current=$(total_used_locks mdc)
3649
3650         local locks_unused_current=$(total_unused_locks mdc)
3651
3652         if (( $locks_current > $locks_orig )); then
3653                 $LCTL set_param -n ldlm.dump_namespaces ""
3654                 error "CURRENT: $locks_current > $locks_orig"
3655         fi
3656         if (( $locks_unused_current > $locks_unused_orig )); then
3657                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3658         fi
3659 }
3660 run_test 29 "IT_GETATTR regression  ============================"
3661
3662 test_30a() { # was test_30
3663         cp $(which ls) $DIR || cp /bin/ls $DIR
3664         $DIR/ls / || error "Can't execute binary from lustre"
3665         rm $DIR/ls
3666 }
3667 run_test 30a "execute binary from Lustre (execve) =============="
3668
3669 test_30b() {
3670         cp `which ls` $DIR || cp /bin/ls $DIR
3671         chmod go+rx $DIR/ls
3672         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3673         rm $DIR/ls
3674 }
3675 run_test 30b "execute binary from Lustre as non-root ==========="
3676
3677 test_30c() { # b=22376
3678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3679
3680         cp $(which ls) $DIR || cp /bin/ls $DIR
3681         chmod a-rw $DIR/ls
3682         cancel_lru_locks mdc
3683         cancel_lru_locks osc
3684         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3685         rm -f $DIR/ls
3686 }
3687 run_test 30c "execute binary from Lustre without read perms ===="
3688
3689 test_30d() {
3690         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3691
3692         for i in {1..10}; do
3693                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3694                 local PID=$!
3695                 sleep 1
3696                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3697                 wait $PID || error "executing dd from Lustre failed"
3698                 rm -f $DIR/$tfile
3699         done
3700
3701         rm -f $DIR/dd
3702 }
3703 run_test 30d "execute binary from Lustre while clear locks"
3704
3705 test_31a() {
3706         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3707         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3708 }
3709 run_test 31a "open-unlink file =================================="
3710
3711 test_31b() {
3712         touch $DIR/f31 || error "touch $DIR/f31 failed"
3713         ln $DIR/f31 $DIR/f31b || error "ln failed"
3714         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3715         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3716 }
3717 run_test 31b "unlink file with multiple links while open ======="
3718
3719 test_31c() {
3720         touch $DIR/f31 || error "touch $DIR/f31 failed"
3721         ln $DIR/f31 $DIR/f31c || error "ln failed"
3722         multiop_bg_pause $DIR/f31 O_uc ||
3723                 error "multiop_bg_pause for $DIR/f31 failed"
3724         MULTIPID=$!
3725         $MULTIOP $DIR/f31c Ouc
3726         kill -USR1 $MULTIPID
3727         wait $MULTIPID
3728 }
3729 run_test 31c "open-unlink file with multiple links ============="
3730
3731 test_31d() {
3732         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3733         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3734 }
3735 run_test 31d "remove of open directory ========================="
3736
3737 test_31e() { # bug 2904
3738         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3739 }
3740 run_test 31e "remove of open non-empty directory ==============="
3741
3742 test_31f() { # bug 4554
3743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3744
3745         set -vx
3746         test_mkdir $DIR/d31f
3747         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3748         cp /etc/hosts $DIR/d31f
3749         ls -l $DIR/d31f
3750         $LFS getstripe $DIR/d31f/hosts
3751         multiop_bg_pause $DIR/d31f D_c || return 1
3752         MULTIPID=$!
3753
3754         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3755         test_mkdir $DIR/d31f
3756         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3757         cp /etc/hosts $DIR/d31f
3758         ls -l $DIR/d31f
3759         $LFS getstripe $DIR/d31f/hosts
3760         multiop_bg_pause $DIR/d31f D_c || return 1
3761         MULTIPID2=$!
3762
3763         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3764         wait $MULTIPID || error "first opendir $MULTIPID failed"
3765
3766         sleep 6
3767
3768         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3769         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3770         set +vx
3771 }
3772 run_test 31f "remove of open directory with open-unlink file ==="
3773
3774 test_31g() {
3775         echo "-- cross directory link --"
3776         test_mkdir -c1 $DIR/${tdir}ga
3777         test_mkdir -c1 $DIR/${tdir}gb
3778         touch $DIR/${tdir}ga/f
3779         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3780         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3781         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3782         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3783         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3784 }
3785 run_test 31g "cross directory link==============="
3786
3787 test_31h() {
3788         echo "-- cross directory link --"
3789         test_mkdir -c1 $DIR/${tdir}
3790         test_mkdir -c1 $DIR/${tdir}/dir
3791         touch $DIR/${tdir}/f
3792         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3793         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3794         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3795         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3796         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3797 }
3798 run_test 31h "cross directory link under child==============="
3799
3800 test_31i() {
3801         echo "-- cross directory link --"
3802         test_mkdir -c1 $DIR/$tdir
3803         test_mkdir -c1 $DIR/$tdir/dir
3804         touch $DIR/$tdir/dir/f
3805         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3806         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3807         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3808         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3809         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3810 }
3811 run_test 31i "cross directory link under parent==============="
3812
3813 test_31j() {
3814         test_mkdir -c1 -p $DIR/$tdir
3815         test_mkdir -c1 -p $DIR/$tdir/dir1
3816         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3817         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3818         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3819         return 0
3820 }
3821 run_test 31j "link for directory"
3822
3823 test_31k() {
3824         test_mkdir -c1 -p $DIR/$tdir
3825         touch $DIR/$tdir/s
3826         touch $DIR/$tdir/exist
3827         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3828         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3829         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3830         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3831         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3832         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3833         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3834         return 0
3835 }
3836 run_test 31k "link to file: the same, non-existing, dir"
3837
3838 test_31l() {
3839         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3840
3841         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3842         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3843                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3844
3845         touch $DIR/$tfile || error "create failed"
3846         mkdir $DIR/$tdir || error "mkdir failed"
3847         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3848 }
3849 run_test 31l "link to file: target dir has trailing slash"
3850
3851 test_31m() {
3852         mkdir $DIR/d31m
3853         touch $DIR/d31m/s
3854         mkdir $DIR/d31m2
3855         touch $DIR/d31m2/exist
3856         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3857         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3858         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3859         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3860         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3861         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3862         return 0
3863 }
3864 run_test 31m "link to file: the same, non-existing, dir"
3865
3866 test_31n() {
3867         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3868         nlink=$(stat --format=%h $DIR/$tfile)
3869         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3870         local fd=$(free_fd)
3871         local cmd="exec $fd<$DIR/$tfile"
3872         eval $cmd
3873         cmd="exec $fd<&-"
3874         trap "eval $cmd" EXIT
3875         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3876         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3877         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3878         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3879         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3880         eval $cmd
3881 }
3882 run_test 31n "check link count of unlinked file"
3883
3884 link_one() {
3885         local tempfile=$(mktemp $1_XXXXXX)
3886         link $tempfile $1 2> /dev/null &&
3887                 echo "$BASHPID: link $tempfile to $1 succeeded"
3888         unlink $tempfile
3889 }
3890
3891 test_31o() { # LU-2901
3892         test_mkdir $DIR/$tdir
3893         for LOOP in $(seq 100); do
3894                 rm -f $DIR/$tdir/$tfile*
3895                 for THREAD in $(seq 8); do
3896                         link_one $DIR/$tdir/$tfile.$LOOP &
3897                 done
3898                 wait
3899                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3900                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3901                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3902                         break || true
3903         done
3904 }
3905 run_test 31o "duplicate hard links with same filename"
3906
3907 test_31p() {
3908         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3909
3910         test_mkdir $DIR/$tdir
3911         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3912         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3913
3914         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3915                 error "open unlink test1 failed"
3916         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3917                 error "open unlink test2 failed"
3918
3919         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3920                 error "test1 still exists"
3921         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3922                 error "test2 still exists"
3923 }
3924 run_test 31p "remove of open striped directory"
3925
3926 test_31q() {
3927         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3928
3929         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3930         index=$($LFS getdirstripe -i $DIR/$tdir)
3931         [ $index -eq 3 ] || error "first stripe index $index != 3"
3932         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3933         [ $index -eq 1 ] || error "second stripe index $index != 1"
3934
3935         # when "-c <stripe_count>" is set, the number of MDTs specified after
3936         # "-i" should equal to the stripe count
3937         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3938 }
3939 run_test 31q "create striped directory on specific MDTs"
3940
3941 #LU-14949
3942 test_31r() {
3943         touch $DIR/$tfile.target
3944         touch $DIR/$tfile.source
3945
3946         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3947         $LCTL set_param fail_loc=0x1419 fail_val=3
3948         cat $DIR/$tfile.target &
3949         CATPID=$!
3950
3951         # Guarantee open is waiting before we get here
3952         sleep 1
3953         mv $DIR/$tfile.source $DIR/$tfile.target
3954
3955         wait $CATPID
3956         RC=$?
3957         if [[ $RC -ne 0 ]]; then
3958                 error "open with cat failed, rc=$RC"
3959         fi
3960 }
3961 run_test 31r "open-rename(replace) race"
3962
3963 cleanup_test32_mount() {
3964         local rc=0
3965         trap 0
3966         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3967         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3968         losetup -d $loopdev || true
3969         rm -rf $DIR/$tdir
3970         return $rc
3971 }
3972
3973 test_32a() {
3974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3975
3976         echo "== more mountpoints and symlinks ================="
3977         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3978         trap cleanup_test32_mount EXIT
3979         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3980         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3981                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3982         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3983                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3984         cleanup_test32_mount
3985 }
3986 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3987
3988 test_32b() {
3989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3990
3991         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3992         trap cleanup_test32_mount EXIT
3993         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3994         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3995                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3996         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3997                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3998         cleanup_test32_mount
3999 }
4000 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
4001
4002 test_32c() {
4003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4004
4005         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4006         trap cleanup_test32_mount EXIT
4007         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4008         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4009                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4010         test_mkdir -p $DIR/$tdir/d2/test_dir
4011         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4012                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
4013         cleanup_test32_mount
4014 }
4015 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
4016
4017 test_32d() {
4018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4019
4020         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4021         trap cleanup_test32_mount EXIT
4022         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4023         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4024                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4025         test_mkdir -p $DIR/$tdir/d2/test_dir
4026         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4027                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
4028         cleanup_test32_mount
4029 }
4030 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
4031
4032 test_32e() {
4033         rm -fr $DIR/$tdir
4034         test_mkdir -p $DIR/$tdir/tmp
4035         local tmp_dir=$DIR/$tdir/tmp
4036         ln -s $DIR/$tdir $tmp_dir/symlink11
4037         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4038         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4039         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4040 }
4041 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4042
4043 test_32f() {
4044         rm -fr $DIR/$tdir
4045         test_mkdir -p $DIR/$tdir/tmp
4046         local tmp_dir=$DIR/$tdir/tmp
4047         ln -s $DIR/$tdir $tmp_dir/symlink11
4048         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4049         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4050         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4051 }
4052 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4053
4054 test_32g() {
4055         local tmp_dir=$DIR/$tdir/tmp
4056         test_mkdir -p $tmp_dir
4057         test_mkdir $DIR/${tdir}2
4058         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4059         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4060         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4061         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4062         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4063         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4064 }
4065 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4066
4067 test_32h() {
4068         rm -fr $DIR/$tdir $DIR/${tdir}2
4069         tmp_dir=$DIR/$tdir/tmp
4070         test_mkdir -p $tmp_dir
4071         test_mkdir $DIR/${tdir}2
4072         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4073         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4074         ls $tmp_dir/symlink12 || error "listing symlink12"
4075         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4076 }
4077 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4078
4079 test_32i() {
4080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4081
4082         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4083         trap cleanup_test32_mount EXIT
4084         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4085         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4086                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4087         touch $DIR/$tdir/test_file
4088         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4089                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4090         cleanup_test32_mount
4091 }
4092 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4093
4094 test_32j() {
4095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4096
4097         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4098         trap cleanup_test32_mount EXIT
4099         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4100         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4101                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4102         touch $DIR/$tdir/test_file
4103         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4104                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4105         cleanup_test32_mount
4106 }
4107 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4108
4109 test_32k() {
4110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4111
4112         rm -fr $DIR/$tdir
4113         trap cleanup_test32_mount EXIT
4114         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4115         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4116                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4117         test_mkdir -p $DIR/$tdir/d2
4118         touch $DIR/$tdir/d2/test_file || error "touch failed"
4119         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4120                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4121         cleanup_test32_mount
4122 }
4123 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4124
4125 test_32l() {
4126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4127
4128         rm -fr $DIR/$tdir
4129         trap cleanup_test32_mount EXIT
4130         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4131         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4132                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4133         test_mkdir -p $DIR/$tdir/d2
4134         touch $DIR/$tdir/d2/test_file || error "touch failed"
4135         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4136                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4137         cleanup_test32_mount
4138 }
4139 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4140
4141 test_32m() {
4142         rm -fr $DIR/d32m
4143         test_mkdir -p $DIR/d32m/tmp
4144         TMP_DIR=$DIR/d32m/tmp
4145         ln -s $DIR $TMP_DIR/symlink11
4146         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4147         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4148                 error "symlink11 not a link"
4149         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4150                 error "symlink01 not a link"
4151 }
4152 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4153
4154 test_32n() {
4155         rm -fr $DIR/d32n
4156         test_mkdir -p $DIR/d32n/tmp
4157         TMP_DIR=$DIR/d32n/tmp
4158         ln -s $DIR $TMP_DIR/symlink11
4159         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4160         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4161         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4162 }
4163 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4164
4165 test_32o() {
4166         touch $DIR/$tfile
4167         test_mkdir -p $DIR/d32o/tmp
4168         TMP_DIR=$DIR/d32o/tmp
4169         ln -s $DIR/$tfile $TMP_DIR/symlink12
4170         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4171         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4172                 error "symlink12 not a link"
4173         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4174         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4175                 error "$DIR/d32o/tmp/symlink12 not file type"
4176         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4177                 error "$DIR/d32o/symlink02 not file type"
4178 }
4179 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4180
4181 test_32p() {
4182         log 32p_1
4183         rm -fr $DIR/d32p
4184         log 32p_2
4185         rm -f $DIR/$tfile
4186         log 32p_3
4187         touch $DIR/$tfile
4188         log 32p_4
4189         test_mkdir -p $DIR/d32p/tmp
4190         log 32p_5
4191         TMP_DIR=$DIR/d32p/tmp
4192         log 32p_6
4193         ln -s $DIR/$tfile $TMP_DIR/symlink12
4194         log 32p_7
4195         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4196         log 32p_8
4197         cat $DIR/d32p/tmp/symlink12 ||
4198                 error "Can't open $DIR/d32p/tmp/symlink12"
4199         log 32p_9
4200         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4201         log 32p_10
4202 }
4203 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4204
4205 test_32q() {
4206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4207
4208         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4209         trap cleanup_test32_mount EXIT
4210         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4211         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4212         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4213                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4214         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4215         cleanup_test32_mount
4216 }
4217 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4218
4219 test_32r() {
4220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4221
4222         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4223         trap cleanup_test32_mount EXIT
4224         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4225         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4226         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4227                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4228         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4229         cleanup_test32_mount
4230 }
4231 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4232
4233 test_33aa() {
4234         rm -f $DIR/$tfile
4235         touch $DIR/$tfile
4236         chmod 444 $DIR/$tfile
4237         chown $RUNAS_ID $DIR/$tfile
4238         log 33_1
4239         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4240         log 33_2
4241 }
4242 run_test 33aa "write file with mode 444 (should return error)"
4243
4244 test_33a() {
4245         rm -fr $DIR/$tdir
4246         test_mkdir $DIR/$tdir
4247         chown $RUNAS_ID $DIR/$tdir
4248         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4249                 error "$RUNAS create $tdir/$tfile failed"
4250         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4251                 error "open RDWR" || true
4252 }
4253 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4254
4255 test_33b() {
4256         rm -fr $DIR/$tdir
4257         test_mkdir $DIR/$tdir
4258         chown $RUNAS_ID $DIR/$tdir
4259         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4260 }
4261 run_test 33b "test open file with malformed flags (No panic)"
4262
4263 test_33c() {
4264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4265         remote_ost_nodsh && skip "remote OST with nodsh"
4266
4267         local ostnum
4268         local ostname
4269         local write_bytes
4270         local all_zeros
4271
4272         all_zeros=true
4273         test_mkdir $DIR/$tdir
4274         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4275
4276         sync
4277         for ostnum in $(seq $OSTCOUNT); do
4278                 # test-framework's OST numbering is one-based, while Lustre's
4279                 # is zero-based
4280                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4281                 # check if at least some write_bytes stats are counted
4282                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4283                               obdfilter.$ostname.stats |
4284                               awk '/^write_bytes/ {print $7}' )
4285                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4286                 if (( ${write_bytes:-0} > 0 )); then
4287                         all_zeros=false
4288                         break
4289                 fi
4290         done
4291
4292         $all_zeros || return 0
4293
4294         # Write four bytes
4295         echo foo > $DIR/$tdir/bar
4296         # Really write them
4297         sync
4298
4299         # Total up write_bytes after writing.  We'd better find non-zeros.
4300         for ostnum in $(seq $OSTCOUNT); do
4301                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4302                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4303                               obdfilter/$ostname/stats |
4304                               awk '/^write_bytes/ {print $7}' )
4305                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4306                 if (( ${write_bytes:-0} > 0 )); then
4307                         all_zeros=false
4308                         break
4309                 fi
4310         done
4311
4312         if $all_zeros; then
4313                 for ostnum in $(seq $OSTCOUNT); do
4314                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4315                         echo "Check write_bytes is in obdfilter.*.stats:"
4316                         do_facet ost$ostnum lctl get_param -n \
4317                                 obdfilter.$ostname.stats
4318                 done
4319                 error "OST not keeping write_bytes stats (b=22312)"
4320         fi
4321 }
4322 run_test 33c "test write_bytes stats"
4323
4324 test_33d() {
4325         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4327
4328         local MDTIDX=1
4329         local remote_dir=$DIR/$tdir/remote_dir
4330
4331         test_mkdir $DIR/$tdir
4332         $LFS mkdir -i $MDTIDX $remote_dir ||
4333                 error "create remote directory failed"
4334
4335         touch $remote_dir/$tfile
4336         chmod 444 $remote_dir/$tfile
4337         chown $RUNAS_ID $remote_dir/$tfile
4338
4339         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4340
4341         chown $RUNAS_ID $remote_dir
4342         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4343                                         error "create" || true
4344         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4345                                     error "open RDWR" || true
4346         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4347 }
4348 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4349
4350 test_33e() {
4351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4352
4353         mkdir $DIR/$tdir
4354
4355         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4356         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4357         mkdir $DIR/$tdir/local_dir
4358
4359         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4360         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4361         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4362
4363         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4364                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4365
4366         rmdir $DIR/$tdir/* || error "rmdir failed"
4367
4368         umask 777
4369         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4370         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4371         mkdir $DIR/$tdir/local_dir
4372
4373         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4374         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4375         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4376
4377         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4378                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4379
4380         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4381
4382         umask 000
4383         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4384         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4385         mkdir $DIR/$tdir/local_dir
4386
4387         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4388         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4389         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4390
4391         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4392                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4393 }
4394 run_test 33e "mkdir and striped directory should have same mode"
4395
4396 cleanup_33f() {
4397         trap 0
4398         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4399 }
4400
4401 test_33f() {
4402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4403         remote_mds_nodsh && skip "remote MDS with nodsh"
4404
4405         mkdir $DIR/$tdir
4406         chmod go+rwx $DIR/$tdir
4407         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4408         trap cleanup_33f EXIT
4409
4410         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4411                 error "cannot create striped directory"
4412
4413         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4414                 error "cannot create files in striped directory"
4415
4416         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4417                 error "cannot remove files in striped directory"
4418
4419         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4420                 error "cannot remove striped directory"
4421
4422         cleanup_33f
4423 }
4424 run_test 33f "nonroot user can create, access, and remove a striped directory"
4425
4426 test_33g() {
4427         mkdir -p $DIR/$tdir/dir2
4428
4429         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4430         echo $err
4431         [[ $err =~ "exists" ]] || error "Not exists error"
4432 }
4433 run_test 33g "nonroot user create already existing root created file"
4434
4435 sub_33h() {
4436         local hash_type=$1
4437         local count=250
4438
4439         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4440                 error "lfs mkdir -H $hash_type $tdir failed"
4441         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4442
4443         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4444         local index2
4445         local fname
4446
4447         for fname in $DIR/$tdir/$tfile.bak \
4448                      $DIR/$tdir/$tfile.SAV \
4449                      $DIR/$tdir/$tfile.orig \
4450                      $DIR/$tdir/$tfile~; do
4451                 touch $fname || error "touch $fname failed"
4452                 index2=$($LFS getstripe -m $fname)
4453                 (( $index == $index2 )) ||
4454                         error "$fname MDT index mismatch $index != $index2"
4455         done
4456
4457         local failed=0
4458         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4459         local pattern
4460
4461         for pattern in ${patterns[*]}; do
4462                 echo "pattern $pattern"
4463                 fname=$DIR/$tdir/$pattern
4464                 for (( i = 0; i < $count; i++ )); do
4465                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4466                                 error "mktemp $DIR/$tdir/$pattern failed"
4467                         index2=$($LFS getstripe -m $fname)
4468                         (( $index == $index2 )) && continue
4469
4470                         failed=$((failed + 1))
4471                         echo "$fname MDT index mismatch $index != $index2"
4472                 done
4473         done
4474
4475         echo "$failed/$count MDT index mismatches, expect ~2-4"
4476         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4477
4478         local same=0
4479         local expect
4480
4481         # verify that "crush" is still broken with all files on same MDT,
4482         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4483         [[ "$hash_type" == "crush" ]] && expect=$count ||
4484                 expect=$((count / MDSCOUNT))
4485
4486         # crush2 doesn't put all-numeric suffixes on the same MDT,
4487         # filename like $tfile.12345678 should *not* be considered temp
4488         for pattern in ${patterns[*]}; do
4489                 local base=${pattern%%X*}
4490                 local suff=${pattern#$base}
4491
4492                 echo "pattern $pattern"
4493                 for (( i = 0; i < $count; i++ )); do
4494                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4495                         touch $fname || error "touch $fname failed"
4496                         index2=$($LFS getstripe -m $fname)
4497                         (( $index != $index2 )) && continue
4498
4499                         same=$((same + 1))
4500                 done
4501         done
4502
4503         # the number of "bad" hashes is random, as it depends on the random
4504         # filenames generated by "mktemp".  Allow some margin in the results.
4505         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4506         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4507            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4508                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4509         same=0
4510
4511         # crush2 doesn't put suffixes with special characters on the same MDT
4512         # filename like $tfile.txt.1234 should *not* be considered temp
4513         for pattern in ${patterns[*]}; do
4514                 local base=${pattern%%X*}
4515                 local suff=${pattern#$base}
4516
4517                 pattern=$base...${suff/XXX}
4518                 echo "pattern=$pattern"
4519                 for (( i = 0; i < $count; i++ )); do
4520                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4521                                 error "touch $fname failed"
4522                         index2=$($LFS getstripe -m $fname)
4523                         (( $index != $index2 )) && continue
4524
4525                         same=$((same + 1))
4526                 done
4527         done
4528
4529         # the number of "bad" hashes is random, as it depends on the random
4530         # filenames generated by "mktemp".  Allow some margin in the results.
4531         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4532         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4533            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4534                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4535 }
4536
4537 test_33h() {
4538         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4539         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4540                 skip "Need MDS version at least 2.13.50"
4541
4542         sub_33h crush
4543 }
4544 run_test 33h "temp file is located on the same MDT as target (crush)"
4545
4546 test_33hh() {
4547         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4548         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4549         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4550                 skip "Need MDS version at least 2.15.0 for crush2"
4551
4552         sub_33h crush2
4553 }
4554 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4555
4556 test_33i()
4557 {
4558         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4559
4560         local FNAME=$(str_repeat 'f' 250)
4561
4562         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4563         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4564
4565         local count
4566         local total
4567
4568         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4569
4570         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4571
4572         lctl --device %$MDC deactivate
4573         stack_trap "lctl --device %$MDC activate"
4574         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4575         total=$(\ls -l $DIR/$tdir | wc -l)
4576         # "ls -l" will list total in the first line
4577         total=$((total - 1))
4578         (( total + count == 1000 )) ||
4579                 error "ls list $total files, $count files on MDT1"
4580 }
4581 run_test 33i "striped directory can be accessed when one MDT is down"
4582
4583 test_33j() {
4584         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4585
4586         mkdir -p $DIR/$tdir/
4587
4588         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4589                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4590
4591         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4592                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4593
4594         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4595                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4596
4597         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4598                 error "-D was not specified, but still failed"
4599 }
4600 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4601
4602 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4603 test_34a() {
4604         rm -f $DIR/f34
4605         $MCREATE $DIR/f34 || error "mcreate failed"
4606         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4607                 error "getstripe failed"
4608         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4609         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4610                 error "getstripe failed"
4611         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4612                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4613 }
4614 run_test 34a "truncate file that has not been opened ==========="
4615
4616 test_34b() {
4617         [ ! -f $DIR/f34 ] && test_34a
4618         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4619                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4620         $OPENFILE -f O_RDONLY $DIR/f34
4621         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4622                 error "getstripe failed"
4623         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4624                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4625 }
4626 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4627
4628 test_34c() {
4629         [ ! -f $DIR/f34 ] && test_34a
4630         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4631                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4632         $OPENFILE -f O_RDWR $DIR/f34
4633         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4634                 error "$LFS getstripe failed"
4635         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4636                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4637 }
4638 run_test 34c "O_RDWR opening file-with-size works =============="
4639
4640 test_34d() {
4641         [ ! -f $DIR/f34 ] && test_34a
4642         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4643                 error "dd failed"
4644         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4645                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4646         rm $DIR/f34
4647 }
4648 run_test 34d "write to sparse file ============================="
4649
4650 test_34e() {
4651         rm -f $DIR/f34e
4652         $MCREATE $DIR/f34e || error "mcreate failed"
4653         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4654         $CHECKSTAT -s 1000 $DIR/f34e ||
4655                 error "Size of $DIR/f34e not equal to 1000 bytes"
4656         $OPENFILE -f O_RDWR $DIR/f34e
4657         $CHECKSTAT -s 1000 $DIR/f34e ||
4658                 error "Size of $DIR/f34e not equal to 1000 bytes"
4659 }
4660 run_test 34e "create objects, some with size and some without =="
4661
4662 test_34f() { # bug 6242, 6243
4663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4664
4665         SIZE34F=48000
4666         rm -f $DIR/f34f
4667         $MCREATE $DIR/f34f || error "mcreate failed"
4668         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4669         dd if=$DIR/f34f of=$TMP/f34f
4670         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4671         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4672         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4673         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4674         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4675 }
4676 run_test 34f "read from a file with no objects until EOF ======="
4677
4678 test_34g() {
4679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4680
4681         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4682                 error "dd failed"
4683         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4684         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4685                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4686         cancel_lru_locks osc
4687         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4688                 error "wrong size after lock cancel"
4689
4690         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4691         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4692                 error "expanding truncate failed"
4693         cancel_lru_locks osc
4694         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4695                 error "wrong expanded size after lock cancel"
4696 }
4697 run_test 34g "truncate long file ==============================="
4698
4699 test_34h() {
4700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4701
4702         local gid=10
4703         local sz=1000
4704
4705         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4706         sync # Flush the cache so that multiop below does not block on cache
4707              # flush when getting the group lock
4708         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4709         MULTIPID=$!
4710
4711         # Since just timed wait is not good enough, let's do a sync write
4712         # that way we are sure enough time for a roundtrip + processing
4713         # passed + 2 seconds of extra margin.
4714         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4715         rm $DIR/${tfile}-1
4716         sleep 2
4717
4718         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4719                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4720                 kill -9 $MULTIPID
4721         fi
4722         wait $MULTIPID
4723         local nsz=`stat -c %s $DIR/$tfile`
4724         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4725 }
4726 run_test 34h "ftruncate file under grouplock should not block"
4727
4728 test_35a() {
4729         cp /bin/sh $DIR/f35a
4730         chmod 444 $DIR/f35a
4731         chown $RUNAS_ID $DIR/f35a
4732         $RUNAS $DIR/f35a && error || true
4733         rm $DIR/f35a
4734 }
4735 run_test 35a "exec file with mode 444 (should return and not leak)"
4736
4737 test_36a() {
4738         rm -f $DIR/f36
4739         utime $DIR/f36 || error "utime failed for MDS"
4740 }
4741 run_test 36a "MDS utime check (mknod, utime)"
4742
4743 test_36b() {
4744         echo "" > $DIR/f36
4745         utime $DIR/f36 || error "utime failed for OST"
4746 }
4747 run_test 36b "OST utime check (open, utime)"
4748
4749 test_36c() {
4750         rm -f $DIR/d36/f36
4751         test_mkdir $DIR/d36
4752         chown $RUNAS_ID $DIR/d36
4753         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4754 }
4755 run_test 36c "non-root MDS utime check (mknod, utime)"
4756
4757 test_36d() {
4758         [ ! -d $DIR/d36 ] && test_36c
4759         echo "" > $DIR/d36/f36
4760         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4761 }
4762 run_test 36d "non-root OST utime check (open, utime)"
4763
4764 test_36e() {
4765         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4766
4767         test_mkdir $DIR/$tdir
4768         touch $DIR/$tdir/$tfile
4769         $RUNAS utime $DIR/$tdir/$tfile &&
4770                 error "utime worked, expected failure" || true
4771 }
4772 run_test 36e "utime on non-owned file (should return error)"
4773
4774 subr_36fh() {
4775         local fl="$1"
4776         local LANG_SAVE=$LANG
4777         local LC_LANG_SAVE=$LC_LANG
4778         export LANG=C LC_LANG=C # for date language
4779
4780         DATESTR="Dec 20  2000"
4781         test_mkdir $DIR/$tdir
4782         lctl set_param fail_loc=$fl
4783         date; date +%s
4784         cp /etc/hosts $DIR/$tdir/$tfile
4785         sync & # write RPC generated with "current" inode timestamp, but delayed
4786         sleep 1
4787         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4788         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4789         cancel_lru_locks $OSC
4790         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4791         date; date +%s
4792         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4793                 echo "BEFORE: $LS_BEFORE" && \
4794                 echo "AFTER : $LS_AFTER" && \
4795                 echo "WANT  : $DATESTR" && \
4796                 error "$DIR/$tdir/$tfile timestamps changed" || true
4797
4798         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4799 }
4800
4801 test_36f() {
4802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4803
4804         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4805         subr_36fh "0x80000214"
4806 }
4807 run_test 36f "utime on file racing with OST BRW write =========="
4808
4809 test_36g() {
4810         remote_ost_nodsh && skip "remote OST with nodsh"
4811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4812         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4813                 skip "Need MDS version at least 2.12.51"
4814
4815         local fmd_max_age
4816         local fmd
4817         local facet="ost1"
4818         local tgt="obdfilter"
4819
4820         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4821
4822         test_mkdir $DIR/$tdir
4823         fmd_max_age=$(do_facet $facet \
4824                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4825                 head -n 1")
4826
4827         echo "FMD max age: ${fmd_max_age}s"
4828         touch $DIR/$tdir/$tfile
4829         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4830                 gawk '{cnt=cnt+$1}  END{print cnt}')
4831         echo "FMD before: $fmd"
4832         [[ $fmd == 0 ]] &&
4833                 error "FMD wasn't create by touch"
4834         sleep $((fmd_max_age + 12))
4835         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4836                 gawk '{cnt=cnt+$1}  END{print cnt}')
4837         echo "FMD after: $fmd"
4838         [[ $fmd == 0 ]] ||
4839                 error "FMD wasn't expired by ping"
4840 }
4841 run_test 36g "FMD cache expiry ====================="
4842
4843 test_36h() {
4844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4845
4846         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4847         subr_36fh "0x80000227"
4848 }
4849 run_test 36h "utime on file racing with OST BRW write =========="
4850
4851 test_36i() {
4852         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4853
4854         test_mkdir $DIR/$tdir
4855         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4856
4857         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4858         local new_mtime=$((mtime + 200))
4859
4860         #change Modify time of striped dir
4861         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4862                         error "change mtime failed"
4863
4864         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4865
4866         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4867 }
4868 run_test 36i "change mtime on striped directory"
4869
4870 # test_37 - duplicate with tests 32q 32r
4871
4872 test_38() {
4873         local file=$DIR/$tfile
4874         touch $file
4875         openfile -f O_DIRECTORY $file
4876         local RC=$?
4877         local ENOTDIR=20
4878         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4879         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4880 }
4881 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4882
4883 test_39a() { # was test_39
4884         touch $DIR/$tfile
4885         touch $DIR/${tfile}2
4886 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4887 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4888 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4889         sleep 2
4890         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4891         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4892                 echo "mtime"
4893                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4894                 echo "atime"
4895                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4896                 echo "ctime"
4897                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4898                 error "O_TRUNC didn't change timestamps"
4899         fi
4900 }
4901 run_test 39a "mtime changed on create"
4902
4903 test_39b() {
4904         test_mkdir -c1 $DIR/$tdir
4905         cp -p /etc/passwd $DIR/$tdir/fopen
4906         cp -p /etc/passwd $DIR/$tdir/flink
4907         cp -p /etc/passwd $DIR/$tdir/funlink
4908         cp -p /etc/passwd $DIR/$tdir/frename
4909         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4910
4911         sleep 1
4912         echo "aaaaaa" >> $DIR/$tdir/fopen
4913         echo "aaaaaa" >> $DIR/$tdir/flink
4914         echo "aaaaaa" >> $DIR/$tdir/funlink
4915         echo "aaaaaa" >> $DIR/$tdir/frename
4916
4917         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4918         local link_new=`stat -c %Y $DIR/$tdir/flink`
4919         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4920         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4921
4922         cat $DIR/$tdir/fopen > /dev/null
4923         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4924         rm -f $DIR/$tdir/funlink2
4925         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4926
4927         for (( i=0; i < 2; i++ )) ; do
4928                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4929                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4930                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4931                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4932
4933                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4934                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4935                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4936                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4937
4938                 cancel_lru_locks $OSC
4939                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4940         done
4941 }
4942 run_test 39b "mtime change on open, link, unlink, rename  ======"
4943
4944 # this should be set to past
4945 TEST_39_MTIME=`date -d "1 year ago" +%s`
4946
4947 # bug 11063
4948 test_39c() {
4949         touch $DIR1/$tfile
4950         sleep 2
4951         local mtime0=`stat -c %Y $DIR1/$tfile`
4952
4953         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4954         local mtime1=`stat -c %Y $DIR1/$tfile`
4955         [ "$mtime1" = $TEST_39_MTIME ] || \
4956                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4957
4958         local d1=`date +%s`
4959         echo hello >> $DIR1/$tfile
4960         local d2=`date +%s`
4961         local mtime2=`stat -c %Y $DIR1/$tfile`
4962         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4963                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4964
4965         mv $DIR1/$tfile $DIR1/$tfile-1
4966
4967         for (( i=0; i < 2; i++ )) ; do
4968                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4969                 [ "$mtime2" = "$mtime3" ] || \
4970                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4971
4972                 cancel_lru_locks $OSC
4973                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4974         done
4975 }
4976 run_test 39c "mtime change on rename ==========================="
4977
4978 # bug 21114
4979 test_39d() {
4980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4981
4982         touch $DIR1/$tfile
4983         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4984
4985         for (( i=0; i < 2; i++ )) ; do
4986                 local mtime=`stat -c %Y $DIR1/$tfile`
4987                 [ $mtime = $TEST_39_MTIME ] || \
4988                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4989
4990                 cancel_lru_locks $OSC
4991                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4992         done
4993 }
4994 run_test 39d "create, utime, stat =============================="
4995
4996 # bug 21114
4997 test_39e() {
4998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4999
5000         touch $DIR1/$tfile
5001         local mtime1=`stat -c %Y $DIR1/$tfile`
5002
5003         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5004
5005         for (( i=0; i < 2; i++ )) ; do
5006                 local mtime2=`stat -c %Y $DIR1/$tfile`
5007                 [ $mtime2 = $TEST_39_MTIME ] || \
5008                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5009
5010                 cancel_lru_locks $OSC
5011                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5012         done
5013 }
5014 run_test 39e "create, stat, utime, stat ========================"
5015
5016 # bug 21114
5017 test_39f() {
5018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5019
5020         touch $DIR1/$tfile
5021         mtime1=`stat -c %Y $DIR1/$tfile`
5022
5023         sleep 2
5024         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5025
5026         for (( i=0; i < 2; i++ )) ; do
5027                 local mtime2=`stat -c %Y $DIR1/$tfile`
5028                 [ $mtime2 = $TEST_39_MTIME ] || \
5029                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5030
5031                 cancel_lru_locks $OSC
5032                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5033         done
5034 }
5035 run_test 39f "create, stat, sleep, utime, stat ================="
5036
5037 # bug 11063
5038 test_39g() {
5039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5040
5041         echo hello >> $DIR1/$tfile
5042         local mtime1=`stat -c %Y $DIR1/$tfile`
5043
5044         sleep 2
5045         chmod o+r $DIR1/$tfile
5046
5047         for (( i=0; i < 2; i++ )) ; do
5048                 local mtime2=`stat -c %Y $DIR1/$tfile`
5049                 [ "$mtime1" = "$mtime2" ] || \
5050                         error "lost mtime: $mtime2, should be $mtime1"
5051
5052                 cancel_lru_locks $OSC
5053                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5054         done
5055 }
5056 run_test 39g "write, chmod, stat ==============================="
5057
5058 # bug 11063
5059 test_39h() {
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         touch $DIR1/$tfile
5063         sleep 1
5064
5065         local d1=`date`
5066         echo hello >> $DIR1/$tfile
5067         local mtime1=`stat -c %Y $DIR1/$tfile`
5068
5069         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5070         local d2=`date`
5071         if [ "$d1" != "$d2" ]; then
5072                 echo "write and touch not within one second"
5073         else
5074                 for (( i=0; i < 2; i++ )) ; do
5075                         local mtime2=`stat -c %Y $DIR1/$tfile`
5076                         [ "$mtime2" = $TEST_39_MTIME ] || \
5077                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5078
5079                         cancel_lru_locks $OSC
5080                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5081                 done
5082         fi
5083 }
5084 run_test 39h "write, utime within one second, stat ============="
5085
5086 test_39i() {
5087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5088
5089         touch $DIR1/$tfile
5090         sleep 1
5091
5092         echo hello >> $DIR1/$tfile
5093         local mtime1=`stat -c %Y $DIR1/$tfile`
5094
5095         mv $DIR1/$tfile $DIR1/$tfile-1
5096
5097         for (( i=0; i < 2; i++ )) ; do
5098                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5099
5100                 [ "$mtime1" = "$mtime2" ] || \
5101                         error "lost mtime: $mtime2, should be $mtime1"
5102
5103                 cancel_lru_locks $OSC
5104                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5105         done
5106 }
5107 run_test 39i "write, rename, stat =============================="
5108
5109 test_39j() {
5110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5111
5112         start_full_debug_logging
5113         touch $DIR1/$tfile
5114         sleep 1
5115
5116         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5117         lctl set_param fail_loc=0x80000412
5118         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5119                 error "multiop failed"
5120         local multipid=$!
5121         local mtime1=`stat -c %Y $DIR1/$tfile`
5122
5123         mv $DIR1/$tfile $DIR1/$tfile-1
5124
5125         kill -USR1 $multipid
5126         wait $multipid || error "multiop close failed"
5127
5128         for (( i=0; i < 2; i++ )) ; do
5129                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5130                 [ "$mtime1" = "$mtime2" ] ||
5131                         error "mtime is lost on close: $mtime2, " \
5132                               "should be $mtime1"
5133
5134                 cancel_lru_locks
5135                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5136         done
5137         lctl set_param fail_loc=0
5138         stop_full_debug_logging
5139 }
5140 run_test 39j "write, rename, close, stat ======================="
5141
5142 test_39k() {
5143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5144
5145         touch $DIR1/$tfile
5146         sleep 1
5147
5148         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5149         local multipid=$!
5150         local mtime1=`stat -c %Y $DIR1/$tfile`
5151
5152         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5153
5154         kill -USR1 $multipid
5155         wait $multipid || error "multiop close failed"
5156
5157         for (( i=0; i < 2; i++ )) ; do
5158                 local mtime2=`stat -c %Y $DIR1/$tfile`
5159
5160                 [ "$mtime2" = $TEST_39_MTIME ] || \
5161                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5162
5163                 cancel_lru_locks
5164                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5165         done
5166 }
5167 run_test 39k "write, utime, close, stat ========================"
5168
5169 # this should be set to future
5170 TEST_39_ATIME=`date -d "1 year" +%s`
5171
5172 test_39l() {
5173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5174         remote_mds_nodsh && skip "remote MDS with nodsh"
5175
5176         local atime_diff=$(do_facet $SINGLEMDS \
5177                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5178         rm -rf $DIR/$tdir
5179         mkdir_on_mdt0 $DIR/$tdir
5180
5181         # test setting directory atime to future
5182         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5183         local atime=$(stat -c %X $DIR/$tdir)
5184         [ "$atime" = $TEST_39_ATIME ] ||
5185                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5186
5187         # test setting directory atime from future to now
5188         local now=$(date +%s)
5189         touch -a -d @$now $DIR/$tdir
5190
5191         atime=$(stat -c %X $DIR/$tdir)
5192         [ "$atime" -eq "$now"  ] ||
5193                 error "atime is not updated from future: $atime, $now"
5194
5195         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5196         sleep 3
5197
5198         # test setting directory atime when now > dir atime + atime_diff
5199         local d1=$(date +%s)
5200         ls $DIR/$tdir
5201         local d2=$(date +%s)
5202         cancel_lru_locks mdc
5203         atime=$(stat -c %X $DIR/$tdir)
5204         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5205                 error "atime is not updated  : $atime, should be $d2"
5206
5207         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5208         sleep 3
5209
5210         # test not setting directory atime when now < dir atime + atime_diff
5211         ls $DIR/$tdir
5212         cancel_lru_locks mdc
5213         atime=$(stat -c %X $DIR/$tdir)
5214         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5215                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5216
5217         do_facet $SINGLEMDS \
5218                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5219 }
5220 run_test 39l "directory atime update ==========================="
5221
5222 test_39m() {
5223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5224
5225         touch $DIR1/$tfile
5226         sleep 2
5227         local far_past_mtime=$(date -d "May 29 1953" +%s)
5228         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5229
5230         touch -m -d @$far_past_mtime $DIR1/$tfile
5231         touch -a -d @$far_past_atime $DIR1/$tfile
5232
5233         for (( i=0; i < 2; i++ )) ; do
5234                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5235                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5236                         error "atime or mtime set incorrectly"
5237
5238                 cancel_lru_locks $OSC
5239                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5240         done
5241 }
5242 run_test 39m "test atime and mtime before 1970"
5243
5244 test_39n() { # LU-3832
5245         remote_mds_nodsh && skip "remote MDS with nodsh"
5246
5247         local atime_diff=$(do_facet $SINGLEMDS \
5248                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5249         local atime0
5250         local atime1
5251         local atime2
5252
5253         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5254
5255         rm -rf $DIR/$tfile
5256         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5257         atime0=$(stat -c %X $DIR/$tfile)
5258
5259         sleep 5
5260         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5261         atime1=$(stat -c %X $DIR/$tfile)
5262
5263         sleep 5
5264         cancel_lru_locks mdc
5265         cancel_lru_locks osc
5266         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5267         atime2=$(stat -c %X $DIR/$tfile)
5268
5269         do_facet $SINGLEMDS \
5270                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5271
5272         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5273         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5274 }
5275 run_test 39n "check that O_NOATIME is honored"
5276
5277 test_39o() {
5278         TESTDIR=$DIR/$tdir/$tfile
5279         [ -e $TESTDIR ] && rm -rf $TESTDIR
5280         mkdir -p $TESTDIR
5281         cd $TESTDIR
5282         links1=2
5283         ls
5284         mkdir a b
5285         ls
5286         links2=$(stat -c %h .)
5287         [ $(($links1 + 2)) != $links2 ] &&
5288                 error "wrong links count $(($links1 + 2)) != $links2"
5289         rmdir b
5290         links3=$(stat -c %h .)
5291         [ $(($links1 + 1)) != $links3 ] &&
5292                 error "wrong links count $links1 != $links3"
5293         return 0
5294 }
5295 run_test 39o "directory cached attributes updated after create"
5296
5297 test_39p() {
5298         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5299
5300         local MDTIDX=1
5301         TESTDIR=$DIR/$tdir/$tdir
5302         [ -e $TESTDIR ] && rm -rf $TESTDIR
5303         test_mkdir -p $TESTDIR
5304         cd $TESTDIR
5305         links1=2
5306         ls
5307         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5308         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5309         ls
5310         links2=$(stat -c %h .)
5311         [ $(($links1 + 2)) != $links2 ] &&
5312                 error "wrong links count $(($links1 + 2)) != $links2"
5313         rmdir remote_dir2
5314         links3=$(stat -c %h .)
5315         [ $(($links1 + 1)) != $links3 ] &&
5316                 error "wrong links count $links1 != $links3"
5317         return 0
5318 }
5319 run_test 39p "remote directory cached attributes updated after create ========"
5320
5321 test_39r() {
5322         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5323                 skip "no atime update on old OST"
5324         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5325                 skip_env "ldiskfs only test"
5326         fi
5327
5328         local saved_adiff
5329         local ahost=$(facet_active_host ost1)
5330         saved_adiff=$(do_facet ost1 \
5331                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5332         stack_trap "do_facet ost1 \
5333                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5334
5335         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5336
5337         $LFS setstripe -i 0 $DIR/$tfile
5338         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5339                 error "can't write initial file"
5340         cancel_lru_locks osc
5341
5342         # exceed atime_diff and access file
5343         sleep 10
5344         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5345                 error "can't udpate atime"
5346
5347         # atime_cli value is in decimal
5348         local atime_cli=$(stat -c %X $DIR/$tfile)
5349         echo "client atime: $atime_cli"
5350
5351         local ostdev=$(ostdevname 1)
5352         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5353         local seq=${fid[3]#0x}
5354         local oid=${fid[1]}
5355         local oid_hex
5356
5357         if [ $seq == 0 ]; then
5358                 oid_hex=${fid[1]}
5359         else
5360                 oid_hex=${fid[2]#0x}
5361         fi
5362         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5363         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5364
5365         # allow atime update to be written to device
5366         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5367         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5368
5369         # Give enough time for server to get updated. Until then
5370         # the value read is defaulted to "0x00000000:00000000"
5371         # Wait until atime read via debugfs is not equal to zero.
5372         # Max limit to wait is 30 seconds.
5373         wait_update_cond $ahost                                         \
5374                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5375                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5376         # atime_ost value is in hex
5377         local atime_ost=$(do_facet ost1 "$cmd" |&
5378                           awk -F'[: ]' '/atime:/ { print $4 }')
5379         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5380         # convert Hex to decimal before comparing
5381         local atime_ost_dec=$((atime_ost))
5382
5383         # The test pass criteria is that the client time and server should
5384         # be same (2s gap accepted). This gap could arise due to VFS updating
5385         # the atime after the read(dd), stat and the updated time from the
5386         # inode
5387         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5388                 error "atime on client $atime_cli != ost $atime_ost_dec"
5389 }
5390 run_test 39r "lazy atime update on OST"
5391
5392 test_39q() { # LU-8041
5393         local testdir=$DIR/$tdir
5394         mkdir -p $testdir
5395         multiop_bg_pause $testdir D_c || error "multiop failed"
5396         local multipid=$!
5397         cancel_lru_locks mdc
5398         kill -USR1 $multipid
5399         local atime=$(stat -c %X $testdir)
5400         [ "$atime" -ne 0 ] || error "atime is zero"
5401 }
5402 run_test 39q "close won't zero out atime"
5403
5404 test_39s() {
5405         local atime0
5406         local atime1
5407         local atime2
5408         local atime3
5409         local atime4
5410
5411         umount_client $MOUNT
5412         mount_client $MOUNT relatime
5413
5414         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5415         atime0=$(stat -c %X $DIR/$tfile)
5416
5417         # First read updates atime
5418         sleep 1
5419         cat $DIR/$tfile >/dev/null
5420         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5421
5422         # Next reads do not update atime
5423         sleep 1
5424         cat $DIR/$tfile >/dev/null
5425         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5426
5427         # If mtime is greater than atime, atime is updated
5428         sleep 1
5429         touch -m $DIR/$tfile # (mtime = now)
5430         sleep 1
5431         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5432         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5433
5434         # Next reads do not update atime
5435         sleep 1
5436         cat $DIR/$tfile >/dev/null
5437         atime4=$(stat -c %X $DIR/$tfile)
5438
5439         # Remount the client to clear 'relatime' option
5440         remount_client $MOUNT
5441
5442         (( atime0 < atime1 )) ||
5443                 error "atime $atime0 should be smaller than $atime1"
5444         (( atime1 == atime2 )) ||
5445                 error "atime $atime1 was updated to $atime2"
5446         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5447         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5448 }
5449 run_test 39s "relatime is supported"
5450
5451 test_40() {
5452         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5453         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5454                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5455         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5456                 error "$tfile is not 4096 bytes in size"
5457 }
5458 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5459
5460 test_41() {
5461         # bug 1553
5462         small_write $DIR/f41 18
5463 }
5464 run_test 41 "test small file write + fstat ====================="
5465
5466 count_ost_writes() {
5467         lctl get_param -n ${OSC}.*.stats |
5468                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5469                         END { printf("%0.0f", writes) }'
5470 }
5471
5472 # decent default
5473 WRITEBACK_SAVE=500
5474 DIRTY_RATIO_SAVE=40
5475 MAX_DIRTY_RATIO=50
5476 BG_DIRTY_RATIO_SAVE=10
5477 MAX_BG_DIRTY_RATIO=25
5478
5479 start_writeback() {
5480         trap 0
5481         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5482         # dirty_ratio, dirty_background_ratio
5483         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5484                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5485                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5486                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5487         else
5488                 # if file not here, we are a 2.4 kernel
5489                 kill -CONT `pidof kupdated`
5490         fi
5491 }
5492
5493 stop_writeback() {
5494         # setup the trap first, so someone cannot exit the test at the
5495         # exact wrong time and mess up a machine
5496         trap start_writeback EXIT
5497         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5498         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5499                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5500                 sysctl -w vm.dirty_writeback_centisecs=0
5501                 sysctl -w vm.dirty_writeback_centisecs=0
5502                 # save and increase /proc/sys/vm/dirty_ratio
5503                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5504                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5505                 # save and increase /proc/sys/vm/dirty_background_ratio
5506                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5507                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5508         else
5509                 # if file not here, we are a 2.4 kernel
5510                 kill -STOP `pidof kupdated`
5511         fi
5512 }
5513
5514 # ensure that all stripes have some grant before we test client-side cache
5515 setup_test42() {
5516         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5517                 dd if=/dev/zero of=$i bs=4k count=1
5518                 rm $i
5519         done
5520 }
5521
5522 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5523 # file truncation, and file removal.
5524 test_42a() {
5525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5526
5527         setup_test42
5528         cancel_lru_locks $OSC
5529         stop_writeback
5530         sync; sleep 1; sync # just to be safe
5531         BEFOREWRITES=`count_ost_writes`
5532         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5533         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5534         AFTERWRITES=`count_ost_writes`
5535         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5536                 error "$BEFOREWRITES < $AFTERWRITES"
5537         start_writeback
5538 }
5539 run_test 42a "ensure that we don't flush on close"
5540
5541 test_42b() {
5542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5543
5544         setup_test42
5545         cancel_lru_locks $OSC
5546         stop_writeback
5547         sync
5548         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5549         BEFOREWRITES=$(count_ost_writes)
5550         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5551         AFTERWRITES=$(count_ost_writes)
5552         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5553                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5554         fi
5555         BEFOREWRITES=$(count_ost_writes)
5556         sync || error "sync: $?"
5557         AFTERWRITES=$(count_ost_writes)
5558         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5559                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5560         fi
5561         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5562         start_writeback
5563         return 0
5564 }
5565 run_test 42b "test destroy of file with cached dirty data ======"
5566
5567 # if these tests just want to test the effect of truncation,
5568 # they have to be very careful.  consider:
5569 # - the first open gets a {0,EOF}PR lock
5570 # - the first write conflicts and gets a {0, count-1}PW
5571 # - the rest of the writes are under {count,EOF}PW
5572 # - the open for truncate tries to match a {0,EOF}PR
5573 #   for the filesize and cancels the PWs.
5574 # any number of fixes (don't get {0,EOF} on open, match
5575 # composite locks, do smarter file size management) fix
5576 # this, but for now we want these tests to verify that
5577 # the cancellation with truncate intent works, so we
5578 # start the file with a full-file pw lock to match against
5579 # until the truncate.
5580 trunc_test() {
5581         test=$1
5582         file=$DIR/$test
5583         offset=$2
5584         cancel_lru_locks $OSC
5585         stop_writeback
5586         # prime the file with 0,EOF PW to match
5587         touch $file
5588         $TRUNCATE $file 0
5589         sync; sync
5590         # now the real test..
5591         dd if=/dev/zero of=$file bs=1024 count=100
5592         BEFOREWRITES=`count_ost_writes`
5593         $TRUNCATE $file $offset
5594         cancel_lru_locks $OSC
5595         AFTERWRITES=`count_ost_writes`
5596         start_writeback
5597 }
5598
5599 test_42c() {
5600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5601
5602         trunc_test 42c 1024
5603         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5604                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5605         rm $file
5606 }
5607 run_test 42c "test partial truncate of file with cached dirty data"
5608
5609 test_42d() {
5610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5611
5612         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5613         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5614         $LCTL set_param debug=+cache
5615
5616         trunc_test 42d 0
5617         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5618                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5619         rm $file
5620 }
5621 run_test 42d "test complete truncate of file with cached dirty data"
5622
5623 test_42e() { # bug22074
5624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5625
5626         local TDIR=$DIR/${tdir}e
5627         local pages=16 # hardcoded 16 pages, don't change it.
5628         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5629         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5630         local max_dirty_mb
5631         local warmup_files
5632
5633         test_mkdir $DIR/${tdir}e
5634         $LFS setstripe -c 1 $TDIR
5635         createmany -o $TDIR/f $files
5636
5637         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5638
5639         # we assume that with $OSTCOUNT files, at least one of them will
5640         # be allocated on OST0.
5641         warmup_files=$((OSTCOUNT * max_dirty_mb))
5642         createmany -o $TDIR/w $warmup_files
5643
5644         # write a large amount of data into one file and sync, to get good
5645         # avail_grant number from OST.
5646         for ((i=0; i<$warmup_files; i++)); do
5647                 idx=$($LFS getstripe -i $TDIR/w$i)
5648                 [ $idx -ne 0 ] && continue
5649                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5650                 break
5651         done
5652         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5653         sync
5654         $LCTL get_param $proc_osc0/cur_dirty_bytes
5655         $LCTL get_param $proc_osc0/cur_grant_bytes
5656
5657         # create as much dirty pages as we can while not to trigger the actual
5658         # RPCs directly. but depends on the env, VFS may trigger flush during this
5659         # period, hopefully we are good.
5660         for ((i=0; i<$warmup_files; i++)); do
5661                 idx=$($LFS getstripe -i $TDIR/w$i)
5662                 [ $idx -ne 0 ] && continue
5663                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5664         done
5665         $LCTL get_param $proc_osc0/cur_dirty_bytes
5666         $LCTL get_param $proc_osc0/cur_grant_bytes
5667
5668         # perform the real test
5669         $LCTL set_param $proc_osc0/rpc_stats 0
5670         for ((;i<$files; i++)); do
5671                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5672                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5673         done
5674         sync
5675         $LCTL get_param $proc_osc0/rpc_stats
5676
5677         local percent=0
5678         local have_ppr=false
5679         $LCTL get_param $proc_osc0/rpc_stats |
5680                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5681                         # skip lines until we are at the RPC histogram data
5682                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5683                         $have_ppr || continue
5684
5685                         # we only want the percent stat for < 16 pages
5686                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5687
5688                         percent=$((percent + WPCT))
5689                         if [[ $percent -gt 15 ]]; then
5690                                 error "less than 16-pages write RPCs" \
5691                                       "$percent% > 15%"
5692                                 break
5693                         fi
5694                 done
5695         rm -rf $TDIR
5696 }
5697 run_test 42e "verify sub-RPC writes are not done synchronously"
5698
5699 test_43A() { # was test_43
5700         test_mkdir $DIR/$tdir
5701         cp -p /bin/ls $DIR/$tdir/$tfile
5702         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5703         pid=$!
5704         # give multiop a chance to open
5705         sleep 1
5706
5707         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5708         kill -USR1 $pid
5709         # Wait for multiop to exit
5710         wait $pid
5711 }
5712 run_test 43A "execution of file opened for write should return -ETXTBSY"
5713
5714 test_43a() {
5715         test_mkdir $DIR/$tdir
5716         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5717         $DIR/$tdir/sleep 60 &
5718         SLEEP_PID=$!
5719         # Make sure exec of $tdir/sleep wins race with truncate
5720         sleep 1
5721         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5722         kill $SLEEP_PID
5723 }
5724 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5725
5726 test_43b() {
5727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5728
5729         test_mkdir $DIR/$tdir
5730         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5731         $DIR/$tdir/sleep 60 &
5732         SLEEP_PID=$!
5733         # Make sure exec of $tdir/sleep wins race with truncate
5734         sleep 1
5735         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5736         kill $SLEEP_PID
5737 }
5738 run_test 43b "truncate of file being executed should return -ETXTBSY"
5739
5740 test_43c() {
5741         local testdir="$DIR/$tdir"
5742         test_mkdir $testdir
5743         cp $SHELL $testdir/
5744         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5745                 ( cd $testdir && md5sum -c )
5746 }
5747 run_test 43c "md5sum of copy into lustre"
5748
5749 test_44A() { # was test_44
5750         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5751
5752         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5753         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5754 }
5755 run_test 44A "zero length read from a sparse stripe"
5756
5757 test_44a() {
5758         local nstripe=$($LFS getstripe -c -d $DIR)
5759         [ -z "$nstripe" ] && skip "can't get stripe info"
5760         [[ $nstripe -gt $OSTCOUNT ]] &&
5761                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5762
5763         local stride=$($LFS getstripe -S -d $DIR)
5764         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5765                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5766         fi
5767
5768         OFFSETS="0 $((stride/2)) $((stride-1))"
5769         for offset in $OFFSETS; do
5770                 for i in $(seq 0 $((nstripe-1))); do
5771                         local GLOBALOFFSETS=""
5772                         # size in Bytes
5773                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5774                         local myfn=$DIR/d44a-$size
5775                         echo "--------writing $myfn at $size"
5776                         ll_sparseness_write $myfn $size ||
5777                                 error "ll_sparseness_write"
5778                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5779                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5780                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5781
5782                         for j in $(seq 0 $((nstripe-1))); do
5783                                 # size in Bytes
5784                                 size=$((((j + $nstripe )*$stride + $offset)))
5785                                 ll_sparseness_write $myfn $size ||
5786                                         error "ll_sparseness_write"
5787                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5788                         done
5789                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5790                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5791                         rm -f $myfn
5792                 done
5793         done
5794 }
5795 run_test 44a "test sparse pwrite ==============================="
5796
5797 dirty_osc_total() {
5798         tot=0
5799         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5800                 tot=$(($tot + $d))
5801         done
5802         echo $tot
5803 }
5804 do_dirty_record() {
5805         before=`dirty_osc_total`
5806         echo executing "\"$*\""
5807         eval $*
5808         after=`dirty_osc_total`
5809         echo before $before, after $after
5810 }
5811 test_45() {
5812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5813
5814         f="$DIR/f45"
5815         # Obtain grants from OST if it supports it
5816         echo blah > ${f}_grant
5817         stop_writeback
5818         sync
5819         do_dirty_record "echo blah > $f"
5820         [[ $before -eq $after ]] && error "write wasn't cached"
5821         do_dirty_record "> $f"
5822         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5823         do_dirty_record "echo blah > $f"
5824         [[ $before -eq $after ]] && error "write wasn't cached"
5825         do_dirty_record "sync"
5826         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5827         do_dirty_record "echo blah > $f"
5828         [[ $before -eq $after ]] && error "write wasn't cached"
5829         do_dirty_record "cancel_lru_locks osc"
5830         [[ $before -gt $after ]] ||
5831                 error "lock cancellation didn't lower dirty count"
5832         start_writeback
5833 }
5834 run_test 45 "osc io page accounting ============================"
5835
5836 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5837 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5838 # objects offset and an assert hit when an rpc was built with 1023's mapped
5839 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5840 test_46() {
5841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5842
5843         f="$DIR/f46"
5844         stop_writeback
5845         sync
5846         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5847         sync
5848         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5849         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5850         sync
5851         start_writeback
5852 }
5853 run_test 46 "dirtying a previously written page ================"
5854
5855 # test_47 is removed "Device nodes check" is moved to test_28
5856
5857 test_48a() { # bug 2399
5858         [ "$mds1_FSTYPE" = "zfs" ] &&
5859         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5860                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5861
5862         test_mkdir $DIR/$tdir
5863         cd $DIR/$tdir
5864         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5865         test_mkdir $DIR/$tdir
5866         touch foo || error "'touch foo' failed after recreating cwd"
5867         test_mkdir bar
5868         touch .foo || error "'touch .foo' failed after recreating cwd"
5869         test_mkdir .bar
5870         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5871         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5872         cd . || error "'cd .' failed after recreating cwd"
5873         mkdir . && error "'mkdir .' worked after recreating cwd"
5874         rmdir . && error "'rmdir .' worked after recreating cwd"
5875         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5876         cd .. || error "'cd ..' failed after recreating cwd"
5877 }
5878 run_test 48a "Access renamed working dir (should return errors)="
5879
5880 test_48b() { # bug 2399
5881         rm -rf $DIR/$tdir
5882         test_mkdir $DIR/$tdir
5883         cd $DIR/$tdir
5884         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5885         touch foo && error "'touch foo' worked after removing cwd"
5886         mkdir foo && error "'mkdir foo' worked after removing cwd"
5887         touch .foo && error "'touch .foo' worked after removing cwd"
5888         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5889         ls . > /dev/null && error "'ls .' worked after removing cwd"
5890         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5891         mkdir . && error "'mkdir .' worked after removing cwd"
5892         rmdir . && error "'rmdir .' worked after removing cwd"
5893         ln -s . foo && error "'ln -s .' worked after removing cwd"
5894         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5895 }
5896 run_test 48b "Access removed working dir (should return errors)="
5897
5898 test_48c() { # bug 2350
5899         #lctl set_param debug=-1
5900         #set -vx
5901         rm -rf $DIR/$tdir
5902         test_mkdir -p $DIR/$tdir/dir
5903         cd $DIR/$tdir/dir
5904         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5905         $TRACE touch foo && error "touch foo worked after removing cwd"
5906         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5907         touch .foo && error "touch .foo worked after removing cwd"
5908         mkdir .foo && error "mkdir .foo worked after removing cwd"
5909         $TRACE ls . && error "'ls .' worked after removing cwd"
5910         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5911         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5912         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5913         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5914         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5915 }
5916 run_test 48c "Access removed working subdir (should return errors)"
5917
5918 test_48d() { # bug 2350
5919         #lctl set_param debug=-1
5920         #set -vx
5921         rm -rf $DIR/$tdir
5922         test_mkdir -p $DIR/$tdir/dir
5923         cd $DIR/$tdir/dir
5924         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5925         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5926         $TRACE touch foo && error "'touch foo' worked after removing parent"
5927         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5928         touch .foo && error "'touch .foo' worked after removing parent"
5929         mkdir .foo && error "mkdir .foo worked after removing parent"
5930         $TRACE ls . && error "'ls .' worked after removing parent"
5931         $TRACE ls .. && error "'ls ..' worked after removing parent"
5932         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5933         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5934         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5935         true
5936 }
5937 run_test 48d "Access removed parent subdir (should return errors)"
5938
5939 test_48e() { # bug 4134
5940         #lctl set_param debug=-1
5941         #set -vx
5942         rm -rf $DIR/$tdir
5943         test_mkdir -p $DIR/$tdir/dir
5944         cd $DIR/$tdir/dir
5945         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5946         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5947         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5948         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5949         # On a buggy kernel addition of "touch foo" after cd .. will
5950         # produce kernel oops in lookup_hash_it
5951         touch ../foo && error "'cd ..' worked after recreate parent"
5952         cd $DIR
5953         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5954 }
5955 run_test 48e "Access to recreated parent subdir (should return errors)"
5956
5957 test_48f() {
5958         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5959                 skip "need MDS >= 2.13.55"
5960         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5961         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5962                 skip "needs different host for mdt1 mdt2"
5963         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5964
5965         $LFS mkdir -i0 $DIR/$tdir
5966         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5967
5968         for d in sub1 sub2 sub3; do
5969                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5970                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5971                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5972         done
5973
5974         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5975 }
5976 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5977
5978 test_49() { # LU-1030
5979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5980         remote_ost_nodsh && skip "remote OST with nodsh"
5981
5982         # get ost1 size - $FSNAME-OST0000
5983         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5984                 awk '{ print $4 }')
5985         # write 800M at maximum
5986         [[ $ost1_size -lt 2 ]] && ost1_size=2
5987         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5988
5989         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5990         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5991         local dd_pid=$!
5992
5993         # change max_pages_per_rpc while writing the file
5994         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5995         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5996         # loop until dd process exits
5997         while ps ax -opid | grep -wq $dd_pid; do
5998                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5999                 sleep $((RANDOM % 5 + 1))
6000         done
6001         # restore original max_pages_per_rpc
6002         $LCTL set_param $osc1_mppc=$orig_mppc
6003         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
6004 }
6005 run_test 49 "Change max_pages_per_rpc won't break osc extent"
6006
6007 test_50() {
6008         # bug 1485
6009         test_mkdir $DIR/$tdir
6010         cd $DIR/$tdir
6011         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
6012 }
6013 run_test 50 "special situations: /proc symlinks  ==============="
6014
6015 test_51a() {    # was test_51
6016         # bug 1516 - create an empty entry right after ".." then split dir
6017         test_mkdir -c1 $DIR/$tdir
6018         touch $DIR/$tdir/foo
6019         $MCREATE $DIR/$tdir/bar
6020         rm $DIR/$tdir/foo
6021         createmany -m $DIR/$tdir/longfile 201
6022         FNUM=202
6023         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
6024                 $MCREATE $DIR/$tdir/longfile$FNUM
6025                 FNUM=$(($FNUM + 1))
6026                 echo -n "+"
6027         done
6028         echo
6029         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
6030 }
6031 run_test 51a "special situations: split htree with empty entry =="
6032
6033 cleanup_print_lfs_df () {
6034         trap 0
6035         $LFS df
6036         $LFS df -i
6037 }
6038
6039 test_51b() {
6040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6041
6042         local dir=$DIR/$tdir
6043         local nrdirs=$((65536 + 100))
6044
6045         # cleanup the directory
6046         rm -fr $dir
6047
6048         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6049
6050         $LFS df
6051         $LFS df -i
6052         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6053         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6054         [[ $numfree -lt $nrdirs ]] &&
6055                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6056
6057         # need to check free space for the directories as well
6058         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6059         numfree=$(( blkfree / $(fs_inode_ksize) ))
6060         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6061
6062         trap cleanup_print_lfs_df EXIT
6063
6064         # create files
6065         createmany -d $dir/d $nrdirs || {
6066                 unlinkmany $dir/d $nrdirs
6067                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6068         }
6069
6070         # really created :
6071         nrdirs=$(ls -U $dir | wc -l)
6072
6073         # unlink all but 100 subdirectories, then check it still works
6074         local left=100
6075         local delete=$((nrdirs - left))
6076
6077         $LFS df
6078         $LFS df -i
6079
6080         # for ldiskfs the nlink count should be 1, but this is OSD specific
6081         # and so this is listed for informational purposes only
6082         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6083         unlinkmany -d $dir/d $delete ||
6084                 error "unlink of first $delete subdirs failed"
6085
6086         echo "nlink between: $(stat -c %h $dir)"
6087         local found=$(ls -U $dir | wc -l)
6088         [ $found -ne $left ] &&
6089                 error "can't find subdirs: found only $found, expected $left"
6090
6091         unlinkmany -d $dir/d $delete $left ||
6092                 error "unlink of second $left subdirs failed"
6093         # regardless of whether the backing filesystem tracks nlink accurately
6094         # or not, the nlink count shouldn't be more than "." and ".." here
6095         local after=$(stat -c %h $dir)
6096         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6097                 echo "nlink after: $after"
6098
6099         cleanup_print_lfs_df
6100 }
6101 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6102
6103 test_51d_sub() {
6104         local stripecount=$1
6105         local nfiles=$2
6106
6107         log "create files with stripecount=$stripecount"
6108         $LFS setstripe -C $stripecount $DIR/$tdir
6109         createmany -o $DIR/$tdir/t- $nfiles
6110         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6111         for ((n = 0; n < $OSTCOUNT; n++)); do
6112                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6113                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6114                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6115                             '($1 == '$n') { objs += 1 } \
6116                             END { printf("%0.0f", objs) }')
6117                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6118         done
6119         unlinkmany $DIR/$tdir/t- $nfiles
6120         rm  -f $TMP/$tfile
6121
6122         local nlast
6123         local min=4
6124         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6125
6126         # For some combinations of stripecount and OSTCOUNT current code
6127         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6128         # than others. Rather than skipping this test entirely, check that
6129         # and keep testing to ensure imbalance does not get worse. LU-15282
6130         (( (OSTCOUNT == 6 && stripecount == 4) ||
6131            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6132            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6133         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6134                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6135                         { $LFS df && $LFS df -i &&
6136                         error "stripecount=$stripecount: " \
6137                               "OST $n has fewer objects vs. OST $nlast " \
6138                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6139                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6140                         { $LFS df && $LFS df -i &&
6141                         error "stripecount=$stripecount: " \
6142                               "OST $n has more objects vs. OST $nlast " \
6143                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6144
6145                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6146                         { $LFS df && $LFS df -i &&
6147                         error "stripecount=$stripecount: " \
6148                               "OST $n has fewer #0 objects vs. OST $nlast " \
6149                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6150                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6151                         { $LFS df && $LFS df -i &&
6152                         error "stripecount=$stripecount: " \
6153                               "OST $n has more #0 objects vs. OST $nlast " \
6154                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6155         done
6156 }
6157
6158 test_51d() {
6159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6160         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6161
6162         local stripecount
6163         local per_ost=100
6164         local nfiles=$((per_ost * OSTCOUNT))
6165         local mdts=$(comma_list $(mdts_nodes))
6166         local param="osp.*.create_count"
6167         local qos_old=$(do_facet mds1 \
6168                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6169
6170         do_nodes $mdts \
6171                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6172         stack_trap "do_nodes $mdts \
6173                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6174
6175         test_mkdir $DIR/$tdir
6176         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6177         (( dirstripes > 0 )) || dirstripes=1
6178
6179         # Ensure enough OST objects precreated for tests to pass without
6180         # running out of objects.  This is an LOV r-r OST algorithm test,
6181         # not an OST object precreation test.
6182         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6183         (( old >= nfiles )) ||
6184         {
6185                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6186
6187                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6188                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6189
6190                 # trigger precreation from all MDTs for all OSTs
6191                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6192                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6193                 done
6194         }
6195
6196         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6197                 sleep 8  # allow object precreation to catch up
6198                 test_51d_sub $stripecount $nfiles
6199         done
6200 }
6201 run_test 51d "check LOV round-robin OST object distribution"
6202
6203 test_51e() {
6204         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6205                 skip_env "ldiskfs only test"
6206         fi
6207
6208         test_mkdir -c1 $DIR/$tdir
6209         test_mkdir -c1 $DIR/$tdir/d0
6210
6211         touch $DIR/$tdir/d0/foo
6212         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6213                 error "file exceed 65000 nlink limit!"
6214         unlinkmany $DIR/$tdir/d0/f- 65001
6215         return 0
6216 }
6217 run_test 51e "check file nlink limit"
6218
6219 test_51f() {
6220         test_mkdir $DIR/$tdir
6221
6222         local max=100000
6223         local ulimit_old=$(ulimit -n)
6224         local spare=20 # number of spare fd's for scripts/libraries, etc.
6225         local mdt=$($LFS getstripe -m $DIR/$tdir)
6226         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6227
6228         echo "MDT$mdt numfree=$numfree, max=$max"
6229         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6230         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6231                 while ! ulimit -n $((numfree + spare)); do
6232                         numfree=$((numfree * 3 / 4))
6233                 done
6234                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6235         else
6236                 echo "left ulimit at $ulimit_old"
6237         fi
6238
6239         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6240                 unlinkmany $DIR/$tdir/f $numfree
6241                 error "create+open $numfree files in $DIR/$tdir failed"
6242         }
6243         ulimit -n $ulimit_old
6244
6245         # if createmany exits at 120s there will be fewer than $numfree files
6246         unlinkmany $DIR/$tdir/f $numfree || true
6247 }
6248 run_test 51f "check many open files limit"
6249
6250 test_52a() {
6251         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6252         test_mkdir $DIR/$tdir
6253         touch $DIR/$tdir/foo
6254         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6255         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6256         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6257         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6258         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6259                                         error "link worked"
6260         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6261         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6262         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6263                                                      error "lsattr"
6264         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6265         cp -r $DIR/$tdir $TMP/
6266         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6267 }
6268 run_test 52a "append-only flag test (should return errors)"
6269
6270 test_52b() {
6271         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6272         test_mkdir $DIR/$tdir
6273         touch $DIR/$tdir/foo
6274         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6275         cat test > $DIR/$tdir/foo && error "cat test worked"
6276         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6277         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6278         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6279                                         error "link worked"
6280         echo foo >> $DIR/$tdir/foo && error "echo worked"
6281         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6282         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6283         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6284         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6285                                                         error "lsattr"
6286         chattr -i $DIR/$tdir/foo || error "chattr failed"
6287
6288         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6289 }
6290 run_test 52b "immutable flag test (should return errors) ======="
6291
6292 test_53() {
6293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6294         remote_mds_nodsh && skip "remote MDS with nodsh"
6295         remote_ost_nodsh && skip "remote OST with nodsh"
6296
6297         local param
6298         local param_seq
6299         local ostname
6300         local mds_last
6301         local mds_last_seq
6302         local ost_last
6303         local ost_last_seq
6304         local ost_last_id
6305         local ostnum
6306         local node
6307         local found=false
6308         local support_last_seq=true
6309
6310         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6311                 support_last_seq=false
6312
6313         # only test MDT0000
6314         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6315         local value
6316         for value in $(do_facet $SINGLEMDS \
6317                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6318                 param=$(echo ${value[0]} | cut -d "=" -f1)
6319                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6320
6321                 if $support_last_seq; then
6322                         param_seq=$(echo $param |
6323                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6324                         mds_last_seq=$(do_facet $SINGLEMDS \
6325                                        $LCTL get_param -n $param_seq)
6326                 fi
6327                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6328
6329                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6330                 node=$(facet_active_host ost$((ostnum+1)))
6331                 param="obdfilter.$ostname.last_id"
6332                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6333                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6334                         ost_last_id=$ost_last
6335
6336                         if $support_last_seq; then
6337                                 ost_last_id=$(echo $ost_last |
6338                                               awk -F':' '{print $2}' |
6339                                               sed -e "s/^0x//g")
6340                                 ost_last_seq=$(echo $ost_last |
6341                                                awk -F':' '{print $1}')
6342                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6343                         fi
6344
6345                         if [[ $ost_last_id != $mds_last ]]; then
6346                                 error "$ost_last_id != $mds_last"
6347                         else
6348                                 found=true
6349                                 break
6350                         fi
6351                 done
6352         done
6353         $found || error "can not match last_seq/last_id for $mdtosc"
6354         return 0
6355 }
6356 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6357
6358 test_54a() {
6359         $SOCKETSERVER $DIR/socket ||
6360                 error "$SOCKETSERVER $DIR/socket failed: $?"
6361         $SOCKETCLIENT $DIR/socket ||
6362                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6363         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6364 }
6365 run_test 54a "unix domain socket test"
6366
6367 test_54b() {
6368         f="$DIR/f54b"
6369         mknod $f c 1 3
6370         chmod 0666 $f
6371         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6372 }
6373 run_test 54b "char device works in lustre ======================"
6374
6375 find_loop_dev() {
6376         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6377         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6378         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6379
6380         for i in $(seq 3 7); do
6381                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6382                 LOOPDEV=$LOOPBASE$i
6383                 LOOPNUM=$i
6384                 break
6385         done
6386 }
6387
6388 cleanup_54c() {
6389         local rc=0
6390         loopdev="$DIR/loop54c"
6391
6392         trap 0
6393         $UMOUNT $DIR/$tdir || rc=$?
6394         losetup -d $loopdev || true
6395         losetup -d $LOOPDEV || true
6396         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6397         return $rc
6398 }
6399
6400 test_54c() {
6401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6402
6403         loopdev="$DIR/loop54c"
6404
6405         find_loop_dev
6406         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6407         trap cleanup_54c EXIT
6408         mknod $loopdev b 7 $LOOPNUM
6409         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6410         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6411         losetup $loopdev $DIR/$tfile ||
6412                 error "can't set up $loopdev for $DIR/$tfile"
6413         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6414         test_mkdir $DIR/$tdir
6415         mount -t ext2 $loopdev $DIR/$tdir ||
6416                 error "error mounting $loopdev on $DIR/$tdir"
6417         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6418                 error "dd write"
6419         df $DIR/$tdir
6420         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6421                 error "dd read"
6422         cleanup_54c
6423 }
6424 run_test 54c "block device works in lustre ====================="
6425
6426 test_54d() {
6427         local pipe="$DIR/$tfile.pipe"
6428         local string="aaaaaa"
6429
6430         mknod $pipe p
6431         echo -n "$string" > $pipe &
6432         local result=$(cat $pipe)
6433         [[ "$result" == "$string" ]] || error "$result != $string"
6434 }
6435 run_test 54d "fifo device works in lustre ======================"
6436
6437 test_54e() {
6438         f="$DIR/f54e"
6439         string="aaaaaa"
6440         cp -aL /dev/console $f
6441         echo $string > $f || error "echo $string to $f failed"
6442 }
6443 run_test 54e "console/tty device works in lustre ======================"
6444
6445 test_55a() {
6446         local dev_path="/sys/kernel/debug/lustre/devices"
6447
6448         load_module kunit/obd_test verbose=2 || error "load_module failed"
6449
6450         # This must be run in iteractive mode, since attach and setup
6451         # are stateful
6452         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6453                 attach obd_test obd_name obd_uuid
6454                 setup obd_test
6455         EOF"
6456
6457         echo "Devices:"
6458         cat "$dev_path" | tail -n 10
6459
6460         $LCTL --device "obd_name" cleanup
6461         $LCTL --device "obd_name" detach
6462
6463         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6464                 error "OBD unit test failed"
6465
6466         rmmod -v obd_test ||
6467                 error "rmmod failed (may trigger a failure in a later test)"
6468 }
6469 run_test 55a "OBD device life cycle unit tests"
6470
6471 test_55b() {
6472         local dev_path="/sys/kernel/debug/lustre/devices"
6473         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6474
6475         # Set up a large number of devices, using the number
6476         # that can be set up in about a minute (based on prior
6477         # testing). We don't want to run this test forever.
6478         local num_dev_to_create="$(( 24000 - $dev_count))"
6479
6480         load_module kunit/obd_test || error "load_module failed"
6481
6482         local start=$SECONDS
6483
6484         # This must be run in iteractive mode, since attach and setup
6485         # are stateful
6486         for ((i = 1; i <= num_dev_to_create; i++)); do
6487                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6488                 echo "setup obd_test_$i"
6489         done | $LCTL || error "OBD device creation failed"
6490
6491         echo "Load time: $((SECONDS - start))"
6492         echo "Devices:"
6493         cat "$dev_path" | tail -n 10
6494
6495         for ((i = 1; i <= num_dev_to_create; i++)); do
6496                 echo "--device obd_name_$i cleanup"
6497                 echo "--device obd_name_$i detach"
6498         done | $LCTL || error "OBD device cleanup failed"
6499
6500         echo "Unload time: $((SECONDS - start))"
6501
6502         rmmod -v obd_test ||
6503                 error "rmmod failed (may trigger a failure in a later test)"
6504 }
6505 run_test 55b "Load and unload max OBD devices"
6506
6507 test_56a() {
6508         local numfiles=3
6509         local numdirs=2
6510         local dir=$DIR/$tdir
6511
6512         rm -rf $dir
6513         test_mkdir -p $dir/dir
6514         for i in $(seq $numfiles); do
6515                 touch $dir/file$i
6516                 touch $dir/dir/file$i
6517         done
6518
6519         local numcomp=$($LFS getstripe --component-count $dir)
6520
6521         [[ $numcomp == 0 ]] && numcomp=1
6522
6523         # test lfs getstripe with --recursive
6524         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6525
6526         [[ $filenum -eq $((numfiles * 2)) ]] ||
6527                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6528         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6529         [[ $filenum -eq $numfiles ]] ||
6530                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6531         echo "$LFS getstripe showed obdidx or l_ost_idx"
6532
6533         # test lfs getstripe with file instead of dir
6534         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6535         [[ $filenum -eq 1 ]] ||
6536                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6537         echo "$LFS getstripe file1 passed"
6538
6539         #test lfs getstripe with --verbose
6540         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6541         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6542                 error "$LFS getstripe --verbose $dir: "\
6543                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6544         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6545                 error "$LFS getstripe $dir: showed lmm_magic"
6546
6547         #test lfs getstripe with -v prints lmm_fid
6548         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6549         local countfids=$(((numdirs + numfiles) * numcomp))
6550         [[ $filenum -eq $countfids ]] ||
6551                 error "$LFS getstripe -v $dir: "\
6552                       "got $filenum want $countfids lmm_fid"
6553         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6554                 error "$LFS getstripe $dir: showed lmm_fid by default"
6555         echo "$LFS getstripe --verbose passed"
6556
6557         #check for FID information
6558         local fid1=$($LFS getstripe --fid $dir/file1)
6559         local fid2=$($LFS getstripe --verbose $dir/file1 |
6560                      awk '/lmm_fid: / { print $2; exit; }')
6561         local fid3=$($LFS path2fid $dir/file1)
6562
6563         [ "$fid1" != "$fid2" ] &&
6564                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6565         [ "$fid1" != "$fid3" ] &&
6566                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6567         echo "$LFS getstripe --fid passed"
6568
6569         #test lfs getstripe with --obd
6570         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6571                 error "$LFS getstripe --obd wrong_uuid: should return error"
6572
6573         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6574
6575         local ostidx=1
6576         local obduuid=$(ostuuid_from_index $ostidx)
6577         local found=$($LFS getstripe -r --obd $obduuid $dir |
6578                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6579
6580         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6581         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6582                 ((filenum--))
6583         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6584                 ((filenum--))
6585
6586         [[ $found -eq $filenum ]] ||
6587                 error "$LFS getstripe --obd: found $found expect $filenum"
6588         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6589                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6590                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6591                 error "$LFS getstripe --obd: should not show file on other obd"
6592         echo "$LFS getstripe --obd passed"
6593 }
6594 run_test 56a "check $LFS getstripe"
6595
6596 test_56b() {
6597         local dir=$DIR/$tdir
6598         local numdirs=3
6599
6600         test_mkdir $dir
6601         for i in $(seq $numdirs); do
6602                 test_mkdir $dir/dir$i
6603         done
6604
6605         # test lfs getdirstripe default mode is non-recursion, which is
6606         # different from lfs getstripe
6607         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6608
6609         [[ $dircnt -eq 1 ]] ||
6610                 error "$LFS getdirstripe: found $dircnt, not 1"
6611         dircnt=$($LFS getdirstripe --recursive $dir |
6612                 grep -c lmv_stripe_count)
6613         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6614                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6615 }
6616 run_test 56b "check $LFS getdirstripe"
6617
6618 test_56bb() {
6619         verify_yaml_available || skip_env "YAML verification not installed"
6620         local output_file=$DIR/$tfile.out
6621
6622         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6623
6624         cat $output_file
6625         cat $output_file | verify_yaml || error "layout is not valid YAML"
6626 }
6627 run_test 56bb "check $LFS getdirstripe layout is YAML"
6628
6629 test_56c() {
6630         remote_ost_nodsh && skip "remote OST with nodsh"
6631
6632         local ost_idx=0
6633         local ost_name=$(ostname_from_index $ost_idx)
6634         local old_status=$(ost_dev_status $ost_idx)
6635         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6636
6637         [[ -z "$old_status" ]] ||
6638                 skip_env "OST $ost_name is in $old_status status"
6639
6640         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6641         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6642                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6643         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6644                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6645                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6646         fi
6647
6648         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6649                 error "$LFS df -v showing inactive devices"
6650         sleep_maxage
6651
6652         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6653
6654         [[ "$new_status" =~ "D" ]] ||
6655                 error "$ost_name status is '$new_status', missing 'D'"
6656         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6657                 [[ "$new_status" =~ "N" ]] ||
6658                         error "$ost_name status is '$new_status', missing 'N'"
6659         fi
6660         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6661                 [[ "$new_status" =~ "f" ]] ||
6662                         error "$ost_name status is '$new_status', missing 'f'"
6663         fi
6664
6665         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6666         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6667                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6668         [[ -z "$p" ]] && restore_lustre_params < $p || true
6669         sleep_maxage
6670
6671         new_status=$(ost_dev_status $ost_idx)
6672         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6673                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6674         # can't check 'f' as devices may actually be on flash
6675 }
6676 run_test 56c "check 'lfs df' showing device status"
6677
6678 test_56d() {
6679         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6680         local osts=$($LFS df -v $MOUNT | grep -c OST)
6681
6682         $LFS df $MOUNT
6683
6684         (( mdts == MDSCOUNT )) ||
6685                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6686         (( osts == OSTCOUNT )) ||
6687                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6688 }
6689 run_test 56d "'lfs df -v' prints only configured devices"
6690
6691 test_56e() {
6692         err_enoent=2 # No such file or directory
6693         err_eopnotsupp=95 # Operation not supported
6694
6695         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6696         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6697
6698         # Check for handling of path not exists
6699         output=$($LFS df $enoent_mnt 2>&1)
6700         ret=$?
6701
6702         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6703         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6704                 error "expect failure $err_enoent, not $ret"
6705
6706         # Check for handling of non-Lustre FS
6707         output=$($LFS df $notsup_mnt)
6708         ret=$?
6709
6710         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6711         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6712                 error "expect success $err_eopnotsupp, not $ret"
6713
6714         # Check for multiple LustreFS argument
6715         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6716         ret=$?
6717
6718         [[ $output -eq 3 && $ret -eq 0 ]] ||
6719                 error "expect success 3, not $output, rc = $ret"
6720
6721         # Check for correct non-Lustre FS handling among multiple
6722         # LustreFS argument
6723         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6724                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6725         ret=$?
6726
6727         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6728                 error "expect success 2, not $output, rc = $ret"
6729 }
6730 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6731
6732 NUMFILES=3
6733 NUMDIRS=3
6734 setup_56() {
6735         local local_tdir="$1"
6736         local local_numfiles="$2"
6737         local local_numdirs="$3"
6738         local dir_params="$4"
6739         local dir_stripe_params="$5"
6740
6741         if [ ! -d "$local_tdir" ] ; then
6742                 test_mkdir -p $dir_stripe_params $local_tdir
6743                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6744                 for i in $(seq $local_numfiles) ; do
6745                         touch $local_tdir/file$i
6746                 done
6747                 for i in $(seq $local_numdirs) ; do
6748                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6749                         for j in $(seq $local_numfiles) ; do
6750                                 touch $local_tdir/dir$i/file$j
6751                         done
6752                 done
6753         fi
6754 }
6755
6756 setup_56_special() {
6757         local local_tdir=$1
6758         local local_numfiles=$2
6759         local local_numdirs=$3
6760
6761         setup_56 $local_tdir $local_numfiles $local_numdirs
6762
6763         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6764                 for i in $(seq $local_numfiles) ; do
6765                         mknod $local_tdir/loop${i}b b 7 $i
6766                         mknod $local_tdir/null${i}c c 1 3
6767                         ln -s $local_tdir/file1 $local_tdir/link${i}
6768                 done
6769                 for i in $(seq $local_numdirs) ; do
6770                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6771                         mknod $local_tdir/dir$i/null${i}c c 1 3
6772                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6773                 done
6774         fi
6775 }
6776
6777 test_56g() {
6778         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6779         local expected=$(($NUMDIRS + 2))
6780
6781         setup_56 $dir $NUMFILES $NUMDIRS
6782
6783         # test lfs find with -name
6784         for i in $(seq $NUMFILES) ; do
6785                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6786
6787                 [ $nums -eq $expected ] ||
6788                         error "lfs find -name '*$i' $dir wrong: "\
6789                               "found $nums, expected $expected"
6790         done
6791 }
6792 run_test 56g "check lfs find -name"
6793
6794 test_56h() {
6795         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6796         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6797
6798         setup_56 $dir $NUMFILES $NUMDIRS
6799
6800         # test lfs find with ! -name
6801         for i in $(seq $NUMFILES) ; do
6802                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6803
6804                 [ $nums -eq $expected ] ||
6805                         error "lfs find ! -name '*$i' $dir wrong: "\
6806                               "found $nums, expected $expected"
6807         done
6808 }
6809 run_test 56h "check lfs find ! -name"
6810
6811 test_56i() {
6812         local dir=$DIR/$tdir
6813
6814         test_mkdir $dir
6815
6816         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6817         local out=$($cmd)
6818
6819         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6820 }
6821 run_test 56i "check 'lfs find -ost UUID' skips directories"
6822
6823 test_56j() {
6824         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6825
6826         setup_56_special $dir $NUMFILES $NUMDIRS
6827
6828         local expected=$((NUMDIRS + 1))
6829         local cmd="$LFS find -type d $dir"
6830         local nums=$($cmd | wc -l)
6831
6832         [ $nums -eq $expected ] ||
6833                 error "'$cmd' wrong: found $nums, expected $expected"
6834 }
6835 run_test 56j "check lfs find -type d"
6836
6837 test_56k() {
6838         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6839
6840         setup_56_special $dir $NUMFILES $NUMDIRS
6841
6842         local expected=$(((NUMDIRS + 1) * NUMFILES))
6843         local cmd="$LFS find -type f $dir"
6844         local nums=$($cmd | wc -l)
6845
6846         [ $nums -eq $expected ] ||
6847                 error "'$cmd' wrong: found $nums, expected $expected"
6848 }
6849 run_test 56k "check lfs find -type f"
6850
6851 test_56l() {
6852         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6853
6854         setup_56_special $dir $NUMFILES $NUMDIRS
6855
6856         local expected=$((NUMDIRS + NUMFILES))
6857         local cmd="$LFS find -type b $dir"
6858         local nums=$($cmd | wc -l)
6859
6860         [ $nums -eq $expected ] ||
6861                 error "'$cmd' wrong: found $nums, expected $expected"
6862 }
6863 run_test 56l "check lfs find -type b"
6864
6865 test_56m() {
6866         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6867
6868         setup_56_special $dir $NUMFILES $NUMDIRS
6869
6870         local expected=$((NUMDIRS + NUMFILES))
6871         local cmd="$LFS find -type c $dir"
6872         local nums=$($cmd | wc -l)
6873         [ $nums -eq $expected ] ||
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875 }
6876 run_test 56m "check lfs find -type c"
6877
6878 test_56n() {
6879         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6880         setup_56_special $dir $NUMFILES $NUMDIRS
6881
6882         local expected=$((NUMDIRS + NUMFILES))
6883         local cmd="$LFS find -type l $dir"
6884         local nums=$($cmd | wc -l)
6885
6886         [ $nums -eq $expected ] ||
6887                 error "'$cmd' wrong: found $nums, expected $expected"
6888 }
6889 run_test 56n "check lfs find -type l"
6890
6891 test_56o() {
6892         local dir=$DIR/$tdir
6893
6894         setup_56 $dir $NUMFILES $NUMDIRS
6895         utime $dir/file1 > /dev/null || error "utime (1)"
6896         utime $dir/file2 > /dev/null || error "utime (2)"
6897         utime $dir/dir1 > /dev/null || error "utime (3)"
6898         utime $dir/dir2 > /dev/null || error "utime (4)"
6899         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6900         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6901
6902         local expected=4
6903         local nums=$($LFS find -mtime +0 $dir | wc -l)
6904
6905         [ $nums -eq $expected ] ||
6906                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6907
6908         expected=12
6909         cmd="$LFS find -mtime 0 $dir"
6910         nums=$($cmd | wc -l)
6911         [ $nums -eq $expected ] ||
6912                 error "'$cmd' wrong: found $nums, expected $expected"
6913 }
6914 run_test 56o "check lfs find -mtime for old files"
6915
6916 test_56ob() {
6917         local dir=$DIR/$tdir
6918         local expected=1
6919         local count=0
6920
6921         # just to make sure there is something that won't be found
6922         test_mkdir $dir
6923         touch $dir/$tfile.now
6924
6925         for age in year week day hour min; do
6926                 count=$((count + 1))
6927
6928                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6929                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6930                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6931
6932                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6933                 local nums=$($cmd | wc -l)
6934                 [ $nums -eq $expected ] ||
6935                         error "'$cmd' wrong: found $nums, expected $expected"
6936
6937                 cmd="$LFS find $dir -atime $count${age:0:1}"
6938                 nums=$($cmd | wc -l)
6939                 [ $nums -eq $expected ] ||
6940                         error "'$cmd' wrong: found $nums, expected $expected"
6941         done
6942
6943         sleep 2
6944         cmd="$LFS find $dir -ctime +1s -type f"
6945         nums=$($cmd | wc -l)
6946         (( $nums == $count * 2 + 1)) ||
6947                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6948 }
6949 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6950
6951 test_newerXY_base() {
6952         local x=$1
6953         local y=$2
6954         local dir=$DIR/$tdir
6955         local ref
6956         local negref
6957
6958         if [ $y == "t" ]; then
6959                 if [ $x == "b" ]; then
6960                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6961                 else
6962                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6963                 fi
6964         else
6965                 ref=$DIR/$tfile.newer.$x$y
6966                 touch $ref || error "touch $ref failed"
6967         fi
6968
6969         echo "before = $ref"
6970         sleep 2
6971         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6972         sleep 2
6973         if [ $y == "t" ]; then
6974                 if [ $x == "b" ]; then
6975                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6976                 else
6977                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6978                 fi
6979         else
6980                 negref=$DIR/$tfile.negnewer.$x$y
6981                 touch $negref || error "touch $negref failed"
6982         fi
6983
6984         echo "after = $negref"
6985         local cmd="$LFS find $dir -newer$x$y $ref"
6986         local nums=$(eval $cmd | wc -l)
6987         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6988
6989         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6990                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6991
6992         cmd="$LFS find $dir ! -newer$x$y $negref"
6993         nums=$(eval $cmd | wc -l)
6994         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6995                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6996
6997         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6998         nums=$(eval $cmd | wc -l)
6999         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
7000                 error "'$cmd' wrong: found $nums between, expected $expected"; }
7001
7002         rm -rf $DIR/*
7003 }
7004
7005 test_56oc() {
7006         test_newerXY_base "a" "a"
7007         test_newerXY_base "a" "m"
7008         test_newerXY_base "a" "c"
7009         test_newerXY_base "m" "a"
7010         test_newerXY_base "m" "m"
7011         test_newerXY_base "m" "c"
7012         test_newerXY_base "c" "a"
7013         test_newerXY_base "c" "m"
7014         test_newerXY_base "c" "c"
7015
7016         test_newerXY_base "a" "t"
7017         test_newerXY_base "m" "t"
7018         test_newerXY_base "c" "t"
7019
7020         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7021            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7022                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7023
7024         test_newerXY_base "b" "b"
7025         test_newerXY_base "b" "t"
7026 }
7027 run_test 56oc "check lfs find -newerXY work"
7028
7029 test_56od() {
7030         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7031                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7032
7033         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7034                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7035
7036         local dir=$DIR/$tdir
7037         local ref=$DIR/$tfile.ref
7038         local negref=$DIR/$tfile.negref
7039
7040         mkdir $dir || error "mkdir $dir failed"
7041         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7042         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7043         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7044         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7045         touch $ref || error "touch $ref failed"
7046         # sleep 3 seconds at least
7047         sleep 3
7048
7049         local before=$(do_facet mds1 date +%s)
7050         local skew=$(($(date +%s) - before + 1))
7051
7052         if (( skew < 0 && skew > -5 )); then
7053                 sleep $((0 - skew + 1))
7054                 skew=0
7055         fi
7056
7057         # Set the dir stripe params to limit files all on MDT0,
7058         # otherwise we need to calc the max clock skew between
7059         # the client and MDTs.
7060         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7061         sleep 2
7062         touch $negref || error "touch $negref failed"
7063
7064         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7065         local nums=$($cmd | wc -l)
7066         local expected=$(((NUMFILES + 1) * NUMDIRS))
7067
7068         [ $nums -eq $expected ] ||
7069                 error "'$cmd' wrong: found $nums, expected $expected"
7070
7071         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7072         nums=$($cmd | wc -l)
7073         expected=$((NUMFILES + 1))
7074         [ $nums -eq $expected ] ||
7075                 error "'$cmd' wrong: found $nums, expected $expected"
7076
7077         [ $skew -lt 0 ] && return
7078
7079         local after=$(do_facet mds1 date +%s)
7080         local age=$((after - before + 1 + skew))
7081
7082         cmd="$LFS find $dir -btime -${age}s -type f"
7083         nums=$($cmd | wc -l)
7084         expected=$(((NUMFILES + 1) * NUMDIRS))
7085
7086         echo "Clock skew between client and server: $skew, age:$age"
7087         [ $nums -eq $expected ] ||
7088                 error "'$cmd' wrong: found $nums, expected $expected"
7089
7090         expected=$(($NUMDIRS + 1))
7091         cmd="$LFS find $dir -btime -${age}s -type d"
7092         nums=$($cmd | wc -l)
7093         [ $nums -eq $expected ] ||
7094                 error "'$cmd' wrong: found $nums, expected $expected"
7095         rm -f $ref $negref || error "Failed to remove $ref $negref"
7096 }
7097 run_test 56od "check lfs find -btime with units"
7098
7099 test_56p() {
7100         [ $RUNAS_ID -eq $UID ] &&
7101                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7102
7103         local dir=$DIR/$tdir
7104
7105         setup_56 $dir $NUMFILES $NUMDIRS
7106         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7107
7108         local expected=$NUMFILES
7109         local cmd="$LFS find -uid $RUNAS_ID $dir"
7110         local nums=$($cmd | wc -l)
7111
7112         [ $nums -eq $expected ] ||
7113                 error "'$cmd' wrong: found $nums, expected $expected"
7114
7115         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7116         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7117         nums=$($cmd | wc -l)
7118         [ $nums -eq $expected ] ||
7119                 error "'$cmd' wrong: found $nums, expected $expected"
7120 }
7121 run_test 56p "check lfs find -uid and ! -uid"
7122
7123 test_56q() {
7124         [ $RUNAS_ID -eq $UID ] &&
7125                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7126
7127         local dir=$DIR/$tdir
7128
7129         setup_56 $dir $NUMFILES $NUMDIRS
7130         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7131
7132         local expected=$NUMFILES
7133         local cmd="$LFS find -gid $RUNAS_GID $dir"
7134         local nums=$($cmd | wc -l)
7135
7136         [ $nums -eq $expected ] ||
7137                 error "'$cmd' wrong: found $nums, expected $expected"
7138
7139         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7140         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7141         nums=$($cmd | wc -l)
7142         [ $nums -eq $expected ] ||
7143                 error "'$cmd' wrong: found $nums, expected $expected"
7144 }
7145 run_test 56q "check lfs find -gid and ! -gid"
7146
7147 test_56r() {
7148         local dir=$DIR/$tdir
7149
7150         setup_56 $dir $NUMFILES $NUMDIRS
7151
7152         local expected=12
7153         local cmd="$LFS find -size 0 -type f -lazy $dir"
7154         local nums=$($cmd | wc -l)
7155
7156         [ $nums -eq $expected ] ||
7157                 error "'$cmd' wrong: found $nums, expected $expected"
7158         cmd="$LFS find -size 0 -type f $dir"
7159         nums=$($cmd | wc -l)
7160         [ $nums -eq $expected ] ||
7161                 error "'$cmd' wrong: found $nums, expected $expected"
7162
7163         expected=0
7164         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7165         nums=$($cmd | wc -l)
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168         cmd="$LFS find ! -size 0 -type f $dir"
7169         nums=$($cmd | wc -l)
7170         [ $nums -eq $expected ] ||
7171                 error "'$cmd' wrong: found $nums, expected $expected"
7172
7173         echo "test" > $dir/$tfile
7174         echo "test2" > $dir/$tfile.2 && sync
7175         expected=1
7176         cmd="$LFS find -size 5c -type f -lazy $dir"
7177         nums=$($cmd | wc -l)
7178         [ $nums -eq $expected ] ||
7179                 error "'$cmd' wrong: found $nums, expected $expected"
7180         cmd="$LFS find -size 5c -type f $dir"
7181         nums=$($cmd | wc -l)
7182         [ $nums -eq $expected ] ||
7183                 error "'$cmd' wrong: found $nums, expected $expected"
7184
7185         expected=1
7186         cmd="$LFS find -size +5c -type f -lazy $dir"
7187         nums=$($cmd | wc -l)
7188         [ $nums -eq $expected ] ||
7189                 error "'$cmd' wrong: found $nums, expected $expected"
7190         cmd="$LFS find -size +5c -type f $dir"
7191         nums=$($cmd | wc -l)
7192         [ $nums -eq $expected ] ||
7193                 error "'$cmd' wrong: found $nums, expected $expected"
7194
7195         expected=2
7196         cmd="$LFS find -size +0 -type f -lazy $dir"
7197         nums=$($cmd | wc -l)
7198         [ $nums -eq $expected ] ||
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200         cmd="$LFS find -size +0 -type f $dir"
7201         nums=$($cmd | wc -l)
7202         [ $nums -eq $expected ] ||
7203                 error "'$cmd' wrong: found $nums, expected $expected"
7204
7205         expected=2
7206         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7207         nums=$($cmd | wc -l)
7208         [ $nums -eq $expected ] ||
7209                 error "'$cmd' wrong: found $nums, expected $expected"
7210         cmd="$LFS find ! -size -5c -type f $dir"
7211         nums=$($cmd | wc -l)
7212         [ $nums -eq $expected ] ||
7213                 error "'$cmd' wrong: found $nums, expected $expected"
7214
7215         expected=12
7216         cmd="$LFS find -size -5c -type f -lazy $dir"
7217         nums=$($cmd | wc -l)
7218         [ $nums -eq $expected ] ||
7219                 error "'$cmd' wrong: found $nums, expected $expected"
7220         cmd="$LFS find -size -5c -type f $dir"
7221         nums=$($cmd | wc -l)
7222         [ $nums -eq $expected ] ||
7223                 error "'$cmd' wrong: found $nums, expected $expected"
7224 }
7225 run_test 56r "check lfs find -size works"
7226
7227 test_56ra_sub() {
7228         local expected=$1
7229         local glimpses=$2
7230         local cmd="$3"
7231
7232         cancel_lru_locks $OSC
7233
7234         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7235         local nums=$($cmd | wc -l)
7236
7237         [ $nums -eq $expected ] ||
7238                 error "'$cmd' wrong: found $nums, expected $expected"
7239
7240         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7241
7242         if (( rpcs_before + glimpses != rpcs_after )); then
7243                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7244                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7245
7246                 if [[ $glimpses == 0 ]]; then
7247                         error "'$cmd' should not send glimpse RPCs to OST"
7248                 else
7249                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7250                 fi
7251         fi
7252 }
7253
7254 test_56ra() {
7255         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7256                 skip "MDS < 2.12.58 doesn't return LSOM data"
7257         local dir=$DIR/$tdir
7258         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7259
7260         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7261
7262         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7263         $LCTL set_param -n llite.*.statahead_agl=0
7264         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7265
7266         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7267         # open and close all files to ensure LSOM is updated
7268         cancel_lru_locks $OSC
7269         find $dir -type f | xargs cat > /dev/null
7270
7271         #   expect_found  glimpse_rpcs  command_to_run
7272         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7273         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7274         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7275         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7276
7277         echo "test" > $dir/$tfile
7278         echo "test2" > $dir/$tfile.2 && sync
7279         cancel_lru_locks $OSC
7280         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7281
7282         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7283         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7284         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7285         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7286
7287         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7288         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7289         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7290         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7291         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7292         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7293 }
7294 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7295
7296 test_56rb() {
7297         local dir=$DIR/$tdir
7298         local tmp=$TMP/$tfile.log
7299         local mdt_idx;
7300
7301         test_mkdir -p $dir || error "failed to mkdir $dir"
7302         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7303                 error "failed to setstripe $dir/$tfile"
7304         mdt_idx=$($LFS getdirstripe -i $dir)
7305         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7306
7307         stack_trap "rm -f $tmp" EXIT
7308         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7309         ! grep -q obd_uuid $tmp ||
7310                 error "failed to find --size +100K --ost 0 $dir"
7311         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7312         ! grep -q obd_uuid $tmp ||
7313                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7314 }
7315 run_test 56rb "check lfs find --size --ost/--mdt works"
7316
7317 test_56rc() {
7318         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7319         local dir=$DIR/$tdir
7320         local found
7321
7322         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7323         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7324         (( $MDSCOUNT > 2 )) &&
7325                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7326         mkdir $dir/$tdir-{1..10}
7327         touch $dir/$tfile-{1..10}
7328
7329         found=$($LFS find $dir --mdt-count 2 | wc -l)
7330         expect=11
7331         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7332
7333         found=$($LFS find $dir -T +1 | wc -l)
7334         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7335         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7336
7337         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7338         expect=11
7339         (( $found == $expect )) || error "found $found all_char, expect $expect"
7340
7341         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7342         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7343         (( $found == $expect )) || error "found $found all_char, expect $expect"
7344 }
7345 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7346
7347 test_56rd() {
7348         local dir=$DIR/$tdir
7349
7350         test_mkdir $dir
7351         rm -f $dir/*
7352
7353         mkfifo $dir/fifo || error "failed to create fifo file"
7354         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7355                 error "should not fail even cannot get projid from pipe file"
7356         found=$($LFS find $dir -t p --printf "%y")
7357         [[ "p" == $found ]] || error "found $found, expect p"
7358
7359         mknod $dir/chardev c 1 5 ||
7360                 error "failed to create character device file"
7361         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7362                 error "should not fail even cannot get projid from chardev file"
7363         found=$($LFS find $dir -t c --printf "%y")
7364         [[ "c" == $found ]] || error "found $found, expect c"
7365
7366         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7367         (( found == 2 )) || error "unable to list all files"
7368 }
7369 run_test 56rd "check lfs find --printf special files"
7370
7371 test_56s() { # LU-611 #LU-9369
7372         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7373
7374         local dir=$DIR/$tdir
7375         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7376
7377         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7378         for i in $(seq $NUMDIRS); do
7379                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7380         done
7381
7382         local expected=$NUMDIRS
7383         local cmd="$LFS find -c $OSTCOUNT $dir"
7384         local nums=$($cmd | wc -l)
7385
7386         [ $nums -eq $expected ] || {
7387                 $LFS getstripe -R $dir
7388                 error "'$cmd' wrong: found $nums, expected $expected"
7389         }
7390
7391         expected=$((NUMDIRS + onestripe))
7392         cmd="$LFS find -stripe-count +0 -type f $dir"
7393         nums=$($cmd | wc -l)
7394         [ $nums -eq $expected ] || {
7395                 $LFS getstripe -R $dir
7396                 error "'$cmd' wrong: found $nums, expected $expected"
7397         }
7398
7399         expected=$onestripe
7400         cmd="$LFS find -stripe-count 1 -type f $dir"
7401         nums=$($cmd | wc -l)
7402         [ $nums -eq $expected ] || {
7403                 $LFS getstripe -R $dir
7404                 error "'$cmd' wrong: found $nums, expected $expected"
7405         }
7406
7407         cmd="$LFS find -stripe-count -2 -type f $dir"
7408         nums=$($cmd | wc -l)
7409         [ $nums -eq $expected ] || {
7410                 $LFS getstripe -R $dir
7411                 error "'$cmd' wrong: found $nums, expected $expected"
7412         }
7413
7414         expected=0
7415         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7416         nums=$($cmd | wc -l)
7417         [ $nums -eq $expected ] || {
7418                 $LFS getstripe -R $dir
7419                 error "'$cmd' wrong: found $nums, expected $expected"
7420         }
7421 }
7422 run_test 56s "check lfs find -stripe-count works"
7423
7424 test_56t() { # LU-611 #LU-9369
7425         local dir=$DIR/$tdir
7426
7427         setup_56 $dir 0 $NUMDIRS
7428         for i in $(seq $NUMDIRS); do
7429                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7430         done
7431
7432         local expected=$NUMDIRS
7433         local cmd="$LFS find -S 8M $dir"
7434         local nums=$($cmd | wc -l)
7435
7436         [ $nums -eq $expected ] || {
7437                 $LFS getstripe -R $dir
7438                 error "'$cmd' wrong: found $nums, expected $expected"
7439         }
7440         rm -rf $dir
7441
7442         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7443
7444         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7445
7446         expected=$(((NUMDIRS + 1) * NUMFILES))
7447         cmd="$LFS find -stripe-size 512k -type f $dir"
7448         nums=$($cmd | wc -l)
7449         [ $nums -eq $expected ] ||
7450                 error "'$cmd' wrong: found $nums, expected $expected"
7451
7452         cmd="$LFS find -stripe-size +320k -type f $dir"
7453         nums=$($cmd | wc -l)
7454         [ $nums -eq $expected ] ||
7455                 error "'$cmd' wrong: found $nums, expected $expected"
7456
7457         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7458         cmd="$LFS find -stripe-size +200k -type f $dir"
7459         nums=$($cmd | wc -l)
7460         [ $nums -eq $expected ] ||
7461                 error "'$cmd' wrong: found $nums, expected $expected"
7462
7463         cmd="$LFS find -stripe-size -640k -type f $dir"
7464         nums=$($cmd | wc -l)
7465         [ $nums -eq $expected ] ||
7466                 error "'$cmd' wrong: found $nums, expected $expected"
7467
7468         expected=4
7469         cmd="$LFS find -stripe-size 256k -type f $dir"
7470         nums=$($cmd | wc -l)
7471         [ $nums -eq $expected ] ||
7472                 error "'$cmd' wrong: found $nums, expected $expected"
7473
7474         cmd="$LFS find -stripe-size -320k -type f $dir"
7475         nums=$($cmd | wc -l)
7476         [ $nums -eq $expected ] ||
7477                 error "'$cmd' wrong: found $nums, expected $expected"
7478
7479         expected=0
7480         cmd="$LFS find -stripe-size 1024k -type f $dir"
7481         nums=$($cmd | wc -l)
7482         [ $nums -eq $expected ] ||
7483                 error "'$cmd' wrong: found $nums, expected $expected"
7484 }
7485 run_test 56t "check lfs find -stripe-size works"
7486
7487 test_56u() { # LU-611
7488         local dir=$DIR/$tdir
7489
7490         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7491
7492         if [[ $OSTCOUNT -gt 1 ]]; then
7493                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7494                 onestripe=4
7495         else
7496                 onestripe=0
7497         fi
7498
7499         local expected=$(((NUMDIRS + 1) * NUMFILES))
7500         local cmd="$LFS find -stripe-index 0 -type f $dir"
7501         local nums=$($cmd | wc -l)
7502
7503         [ $nums -eq $expected ] ||
7504                 error "'$cmd' wrong: found $nums, expected $expected"
7505
7506         expected=$onestripe
7507         cmd="$LFS find -stripe-index 1 -type f $dir"
7508         nums=$($cmd | wc -l)
7509         [ $nums -eq $expected ] ||
7510                 error "'$cmd' wrong: found $nums, expected $expected"
7511
7512         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7513         nums=$($cmd | wc -l)
7514         [ $nums -eq $expected ] ||
7515                 error "'$cmd' wrong: found $nums, expected $expected"
7516
7517         expected=0
7518         # This should produce an error and not return any files
7519         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7520         nums=$($cmd 2>/dev/null | wc -l)
7521         [ $nums -eq $expected ] ||
7522                 error "'$cmd' wrong: found $nums, expected $expected"
7523
7524         if [[ $OSTCOUNT -gt 1 ]]; then
7525                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7526                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7527                 nums=$($cmd | wc -l)
7528                 [ $nums -eq $expected ] ||
7529                         error "'$cmd' wrong: found $nums, expected $expected"
7530         fi
7531 }
7532 run_test 56u "check lfs find -stripe-index works"
7533
7534 test_56v() {
7535         local mdt_idx=0
7536         local dir=$DIR/$tdir
7537
7538         setup_56 $dir $NUMFILES $NUMDIRS
7539
7540         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7541         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7542
7543         for file in $($LFS find -m $UUID $dir); do
7544                 file_midx=$($LFS getstripe -m $file)
7545                 [ $file_midx -eq $mdt_idx ] ||
7546                         error "lfs find -m $UUID != getstripe -m $file_midx"
7547         done
7548 }
7549 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7550
7551 test_56wa() {
7552         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7554
7555         local dir=$DIR/$tdir
7556
7557         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7558         stack_trap "rm -rf $dir"
7559
7560         local stripe_size=$($LFS getstripe -S -d $dir) ||
7561                 error "$LFS getstripe -S -d $dir failed"
7562         stripe_size=${stripe_size%% *}
7563
7564         local file_size=$((stripe_size * OSTCOUNT))
7565         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7566         local required_space=$((file_num * file_size))
7567         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7568                            head -n1)
7569         (( free_space >= required_space / 1024 )) ||
7570                 skip_env "need $required_space, have $free_space kbytes"
7571
7572         local dd_bs=65536
7573         local dd_count=$((file_size / dd_bs))
7574
7575         # write data into the files
7576         local i
7577         local j
7578         local file
7579
7580         for ((i = 1; i <= NUMFILES; i++ )); do
7581                 file=$dir/file$i
7582                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7583                         error "write data into $file failed"
7584         done
7585         for ((i = 1; i <= NUMDIRS; i++ )); do
7586                 for ((j = 1; j <= NUMFILES; j++ )); do
7587                         file=$dir/dir$i/file$j
7588                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7589                                 error "write data into $file failed"
7590                 done
7591         done
7592
7593         # $LFS_MIGRATE will fail if hard link migration is unsupported
7594         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7595                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7596                         error "creating links to $dir/dir1/file1 failed"
7597         fi
7598
7599         local expected=-1
7600
7601         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7602
7603         # lfs_migrate file
7604         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7605
7606         echo "$cmd"
7607         eval $cmd || error "$cmd failed"
7608
7609         check_stripe_count $dir/file1 $expected
7610
7611         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7612                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7613                 # OST 1 if it is on OST 0. This file is small enough to
7614                 # be on only one stripe.
7615                 file=$dir/migr_1_ost
7616                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7617                         error "write data into $file failed"
7618                 local obdidx=$($LFS getstripe -i $file)
7619                 local oldmd5=$(md5sum $file)
7620                 local newobdidx=0
7621
7622                 (( obdidx != 0 )) || newobdidx=1
7623                 cmd="$LFS migrate -i $newobdidx $file"
7624                 echo $cmd
7625                 eval $cmd || error "$cmd failed"
7626
7627                 local realobdix=$($LFS getstripe -i $file)
7628                 local newmd5=$(md5sum $file)
7629
7630                 (( $newobdidx == $realobdix )) ||
7631                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7632                 [[ "$oldmd5" == "$newmd5" ]] ||
7633                         error "md5sum differ: $oldmd5, $newmd5"
7634         fi
7635
7636         # lfs_migrate dir
7637         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7638         echo "$cmd"
7639         eval $cmd || error "$cmd failed"
7640
7641         for (( j = 1; j <= NUMFILES; j++ )); do
7642                 check_stripe_count $dir/dir1/file$j $expected
7643         done
7644
7645         # lfs_migrate works with lfs find
7646         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7647              $LFS_MIGRATE -y -c $expected"
7648         echo "$cmd"
7649         eval $cmd || error "$cmd failed"
7650
7651         for (( i = 2; i <= NUMFILES; i++ )); do
7652                 check_stripe_count $dir/file$i $expected
7653         done
7654         for (( i = 2; i <= NUMDIRS; i++ )); do
7655                 for (( j = 1; j <= NUMFILES; j++ )); do
7656                         check_stripe_count $dir/dir$i/file$j $expected
7657                 done
7658         done
7659 }
7660 run_test 56wa "check lfs_migrate -c stripe_count works"
7661
7662 test_56wb() {
7663         local file1=$DIR/$tdir/file1
7664         local create_pool=false
7665         local initial_pool=$($LFS getstripe -p $DIR)
7666         local pool_list=()
7667         local pool=""
7668
7669         echo -n "Creating test dir..."
7670         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7671         echo "done."
7672
7673         echo -n "Creating test file..."
7674         touch $file1 || error "cannot create file"
7675         echo "done."
7676
7677         echo -n "Detecting existing pools..."
7678         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7679
7680         if [ ${#pool_list[@]} -gt 0 ]; then
7681                 echo "${pool_list[@]}"
7682                 for thispool in "${pool_list[@]}"; do
7683                         if [[ -z "$initial_pool" ||
7684                               "$initial_pool" != "$thispool" ]]; then
7685                                 pool="$thispool"
7686                                 echo "Using existing pool '$pool'"
7687                                 break
7688                         fi
7689                 done
7690         else
7691                 echo "none detected."
7692         fi
7693         if [ -z "$pool" ]; then
7694                 pool=${POOL:-testpool}
7695                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7696                 echo -n "Creating pool '$pool'..."
7697                 create_pool=true
7698                 pool_add $pool &> /dev/null ||
7699                         error "pool_add failed"
7700                 echo "done."
7701
7702                 echo -n "Adding target to pool..."
7703                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7704                         error "pool_add_targets failed"
7705                 echo "done."
7706         fi
7707
7708         echo -n "Setting pool using -p option..."
7709         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7710                 error "migrate failed rc = $?"
7711         echo "done."
7712
7713         echo -n "Verifying test file is in pool after migrating..."
7714         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7715                 error "file was not migrated to pool $pool"
7716         echo "done."
7717
7718         echo -n "Removing test file from pool '$pool'..."
7719         # "lfs migrate $file" won't remove the file from the pool
7720         # until some striping information is changed.
7721         $LFS migrate -c 1 $file1 &> /dev/null ||
7722                 error "cannot remove from pool"
7723         [ "$($LFS getstripe -p $file1)" ] &&
7724                 error "pool still set"
7725         echo "done."
7726
7727         echo -n "Setting pool using --pool option..."
7728         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7729                 error "migrate failed rc = $?"
7730         echo "done."
7731
7732         # Clean up
7733         rm -f $file1
7734         if $create_pool; then
7735                 destroy_test_pools 2> /dev/null ||
7736                         error "destroy test pools failed"
7737         fi
7738 }
7739 run_test 56wb "check lfs_migrate pool support"
7740
7741 test_56wc() {
7742         local file1="$DIR/$tdir/$tfile"
7743         local md5
7744         local parent_ssize
7745         local parent_scount
7746         local cur_ssize
7747         local cur_scount
7748         local orig_ssize
7749         local new_scount
7750         local cur_comp
7751
7752         echo -n "Creating test dir..."
7753         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7754         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7755                 error "cannot set stripe by '-S 1M -c 1'"
7756         echo "done"
7757
7758         echo -n "Setting initial stripe for test file..."
7759         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7760                 error "cannot set stripe"
7761         cur_ssize=$($LFS getstripe -S "$file1")
7762         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7763         echo "done."
7764
7765         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7766         stack_trap "rm -f $file1"
7767         md5="$(md5sum $file1)"
7768
7769         # File currently set to -S 512K -c 1
7770
7771         # Ensure -c and -S options are rejected when -R is set
7772         echo -n "Verifying incompatible options are detected..."
7773         $LFS_MIGRATE -R -c 1 "$file1" &&
7774                 error "incompatible -R and -c options not detected"
7775         $LFS_MIGRATE -R -S 1M "$file1" &&
7776                 error "incompatible -R and -S options not detected"
7777         $LFS_MIGRATE -R -p pool "$file1" &&
7778                 error "incompatible -R and -p options not detected"
7779         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7780                 error "incompatible -R and -E options not detected"
7781         $LFS_MIGRATE -R -A "$file1" &&
7782                 error "incompatible -R and -A options not detected"
7783         $LFS_MIGRATE -A -c 1 "$file1" &&
7784                 error "incompatible -A and -c options not detected"
7785         $LFS_MIGRATE -A -S 1M "$file1" &&
7786                 error "incompatible -A and -S options not detected"
7787         $LFS_MIGRATE -A -p pool "$file1" &&
7788                 error "incompatible -A and -p options not detected"
7789         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7790                 error "incompatible -A and -E options not detected"
7791         echo "done."
7792
7793         # Ensure unrecognized options are passed through to 'lfs migrate'
7794         echo -n "Verifying -S option is passed through to lfs migrate..."
7795         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7796         cur_ssize=$($LFS getstripe -S "$file1")
7797         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7798         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7799         echo "done."
7800
7801         # File currently set to -S 1M -c 1
7802
7803         # Ensure long options are supported
7804         echo -n "Verifying long options supported..."
7805         $LFS_MIGRATE --non-block "$file1" ||
7806                 error "long option without argument not supported"
7807         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7808                 error "long option with argument not supported"
7809         cur_ssize=$($LFS getstripe -S "$file1")
7810         (( cur_ssize == 524288 )) ||
7811                 error "migrate --stripe-size $cur_ssize != 524288"
7812         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7813         echo "done."
7814
7815         # File currently set to -S 512K -c 1
7816
7817         if (( OSTCOUNT > 1 )); then
7818                 echo -n "Verifying explicit stripe count can be set..."
7819                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7820                 cur_scount=$($LFS getstripe -c "$file1")
7821                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7822                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7823                         error "file data has changed (3)"
7824                 echo "done."
7825         fi
7826
7827         # File currently set to -S 512K -c 1 or -S 512K -c 2
7828
7829         # Ensure parent striping is used if -R is set, and no stripe
7830         # count or size is specified
7831         echo -n "Setting stripe for parent directory..."
7832         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7833                 error "cannot set stripe '-S 2M -c 1'"
7834         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7835         echo "done."
7836
7837         echo -n "Verifying restripe option uses parent stripe settings..."
7838         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7839         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7840         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7841         cur_ssize=$($LFS getstripe -S "$file1")
7842         (( cur_ssize == parent_ssize )) ||
7843                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7844         cur_scount=$($LFS getstripe -c "$file1")
7845         (( cur_scount == parent_scount )) ||
7846                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7847         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7848         echo "done."
7849
7850         # File currently set to -S 1M -c 1
7851
7852         # Ensure striping is preserved if -R is not set, and no stripe
7853         # count or size is specified
7854         echo -n "Verifying striping size preserved when not specified..."
7855         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7856         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7857                 error "cannot set stripe on parent directory"
7858         $LFS_MIGRATE "$file1" || error "migrate failed"
7859         cur_ssize=$($LFS getstripe -S "$file1")
7860         (( cur_ssize == orig_ssize )) ||
7861                 error "migrate by default $cur_ssize != $orig_ssize"
7862         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7863         echo "done."
7864
7865         # Ensure file name properly detected when final option has no argument
7866         echo -n "Verifying file name properly detected..."
7867         $LFS_MIGRATE "$file1" ||
7868                 error "file name interpreted as option argument"
7869         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7870         echo "done."
7871
7872         # Ensure PFL arguments are passed through properly
7873         echo -n "Verifying PFL options passed through..."
7874         new_scount=$(((OSTCOUNT + 1) / 2))
7875         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7876                 error "migrate PFL arguments failed"
7877         cur_comp=$($LFS getstripe --comp-count $file1)
7878         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7879         cur_scount=$($LFS getstripe --stripe-count $file1)
7880         (( cur_scount == new_scount)) ||
7881                 error "PFL stripe count $cur_scount != $new_scount"
7882         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7883         echo "done."
7884 }
7885 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7886
7887 test_56wd() {
7888         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7889
7890         local file1=$DIR/$tdir/$tfile
7891
7892         echo -n "Creating test dir..."
7893         test_mkdir $DIR/$tdir || error "cannot create dir"
7894         echo "done."
7895
7896         echo -n "Creating test file..."
7897         echo "$tfile" > $file1
7898         echo "done."
7899
7900         # Ensure 'lfs migrate' will fail by using a non-existent option,
7901         # and make sure rsync is not called to recover
7902         echo -n "Make sure --no-rsync option works..."
7903         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7904                 grep -q 'refusing to fall back to rsync' ||
7905                 error "rsync was called with --no-rsync set"
7906         echo "done."
7907
7908         # Ensure rsync is called without trying 'lfs migrate' first
7909         echo -n "Make sure --rsync option works..."
7910         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7911                 grep -q 'falling back to rsync' &&
7912                 error "lfs migrate was called with --rsync set"
7913         echo "done."
7914 }
7915 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7916
7917 test_56we() {
7918         local td=$DIR/$tdir
7919         local tf=$td/$tfile
7920
7921         test_mkdir $td || error "cannot create $td"
7922         touch $tf || error "cannot touch $tf"
7923
7924         echo -n "Make sure --non-direct|-D works..."
7925         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7926                 grep -q "lfs migrate --non-direct" ||
7927                 error "--non-direct option cannot work correctly"
7928         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7929                 grep -q "lfs migrate -D" ||
7930                 error "-D option cannot work correctly"
7931         echo "done."
7932 }
7933 run_test 56we "check lfs_migrate --non-direct|-D support"
7934
7935 test_56x() {
7936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7937         check_swap_layouts_support
7938
7939         local dir=$DIR/$tdir
7940         local ref1=/etc/passwd
7941         local file1=$dir/file1
7942
7943         test_mkdir $dir || error "creating dir $dir"
7944         $LFS setstripe -c 2 $file1
7945         cp $ref1 $file1
7946         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7947         stripe=$($LFS getstripe -c $file1)
7948         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7949         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7950
7951         # clean up
7952         rm -f $file1
7953 }
7954 run_test 56x "lfs migration support"
7955
7956 test_56xa() {
7957         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7958         check_swap_layouts_support
7959
7960         local dir=$DIR/$tdir/$testnum
7961
7962         test_mkdir -p $dir
7963
7964         local ref1=/etc/passwd
7965         local file1=$dir/file1
7966
7967         $LFS setstripe -c 2 $file1
7968         cp $ref1 $file1
7969         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7970
7971         local stripe=$($LFS getstripe -c $file1)
7972
7973         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7974         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7975
7976         # clean up
7977         rm -f $file1
7978 }
7979 run_test 56xa "lfs migration --block support"
7980
7981 check_migrate_links() {
7982         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7983         local dir="$1"
7984         local file1="$dir/file1"
7985         local begin="$2"
7986         local count="$3"
7987         local runas="$4"
7988         local total_count=$(($begin + $count - 1))
7989         local symlink_count=10
7990         local uniq_count=10
7991
7992         if [ ! -f "$file1" ]; then
7993                 echo -n "creating initial file..."
7994                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7995                         error "cannot setstripe initial file"
7996                 echo "done"
7997
7998                 echo -n "creating symlinks..."
7999                 for s in $(seq 1 $symlink_count); do
8000                         ln -s "$file1" "$dir/slink$s" ||
8001                                 error "cannot create symlinks"
8002                 done
8003                 echo "done"
8004
8005                 echo -n "creating nonlinked files..."
8006                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
8007                         error "cannot create nonlinked files"
8008                 echo "done"
8009         fi
8010
8011         # create hard links
8012         if [ ! -f "$dir/file$total_count" ]; then
8013                 echo -n "creating hard links $begin:$total_count..."
8014                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
8015                         /dev/null || error "cannot create hard links"
8016                 echo "done"
8017         fi
8018
8019         echo -n "checking number of hard links listed in xattrs..."
8020         local fid=$($LFS getstripe -F "$file1")
8021         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8022
8023         echo "${#paths[*]}"
8024         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8025                         skip "hard link list has unexpected size, skipping test"
8026         fi
8027         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8028                         error "link names should exceed xattrs size"
8029         fi
8030
8031         echo -n "migrating files..."
8032         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8033         local rc=$?
8034         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8035         echo "done"
8036
8037         # make sure all links have been properly migrated
8038         echo -n "verifying files..."
8039         fid=$($LFS getstripe -F "$file1") ||
8040                 error "cannot get fid for file $file1"
8041         for i in $(seq 2 $total_count); do
8042                 local fid2=$($LFS getstripe -F $dir/file$i)
8043
8044                 [ "$fid2" == "$fid" ] ||
8045                         error "migrated hard link has mismatched FID"
8046         done
8047
8048         # make sure hard links were properly detected, and migration was
8049         # performed only once for the entire link set; nonlinked files should
8050         # also be migrated
8051         local actual=$(grep -c 'done' <<< "$migrate_out")
8052         local expected=$(($uniq_count + 1))
8053
8054         [ "$actual" -eq  "$expected" ] ||
8055                 error "hard links individually migrated ($actual != $expected)"
8056
8057         # make sure the correct number of hard links are present
8058         local hardlinks=$(stat -c '%h' "$file1")
8059
8060         [ $hardlinks -eq $total_count ] ||
8061                 error "num hard links $hardlinks != $total_count"
8062         echo "done"
8063
8064         return 0
8065 }
8066
8067 test_56xb() {
8068         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8069                 skip "Need MDS version at least 2.10.55"
8070
8071         local dir="$DIR/$tdir"
8072
8073         test_mkdir "$dir" || error "cannot create dir $dir"
8074
8075         echo "testing lfs migrate mode when all links fit within xattrs"
8076         check_migrate_links "$dir" 2 99
8077
8078         echo "testing rsync mode when all links fit within xattrs"
8079         check_migrate_links --rsync "$dir" 2 99
8080
8081         echo "testing lfs migrate mode when all links do not fit within xattrs"
8082         check_migrate_links "$dir" 101 100
8083
8084         echo "testing rsync mode when all links do not fit within xattrs"
8085         check_migrate_links --rsync "$dir" 101 100
8086
8087         chown -R $RUNAS_ID $dir
8088         echo "testing non-root lfs migrate mode when not all links are in xattr"
8089         check_migrate_links "$dir" 101 100 "$RUNAS"
8090
8091         # clean up
8092         rm -rf $dir
8093 }
8094 run_test 56xb "lfs migration hard link support"
8095
8096 test_56xc() {
8097         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8098
8099         local dir="$DIR/$tdir"
8100
8101         test_mkdir "$dir" || error "cannot create dir $dir"
8102
8103         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8104         echo -n "Setting initial stripe for 20MB test file..."
8105         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8106                 error "cannot setstripe 20MB file"
8107         echo "done"
8108         echo -n "Sizing 20MB test file..."
8109         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8110         echo "done"
8111         echo -n "Verifying small file autostripe count is 1..."
8112         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8113                 error "cannot migrate 20MB file"
8114         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8115                 error "cannot get stripe for $dir/20mb"
8116         [ $stripe_count -eq 1 ] ||
8117                 error "unexpected stripe count $stripe_count for 20MB file"
8118         rm -f "$dir/20mb"
8119         echo "done"
8120
8121         # Test 2: File is small enough to fit within the available space on
8122         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8123         # have at least an additional 1KB for each desired stripe for test 3
8124         echo -n "Setting stripe for 1GB test file..."
8125         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8126         echo "done"
8127         echo -n "Sizing 1GB test file..."
8128         # File size is 1GB + 3KB
8129         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8130         echo "done"
8131
8132         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8133         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8134         if (( avail > 524288 * OSTCOUNT )); then
8135                 echo -n "Migrating 1GB file..."
8136                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8137                         error "cannot migrate 1GB file"
8138                 echo "done"
8139                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8140                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8141                         error "cannot getstripe for 1GB file"
8142                 [ $stripe_count -eq 2 ] ||
8143                         error "unexpected stripe count $stripe_count != 2"
8144                 echo "done"
8145         fi
8146
8147         # Test 3: File is too large to fit within the available space on
8148         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8149         if [ $OSTCOUNT -ge 3 ]; then
8150                 # The required available space is calculated as
8151                 # file size (1GB + 3KB) / OST count (3).
8152                 local kb_per_ost=349526
8153
8154                 echo -n "Migrating 1GB file with limit..."
8155                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8156                         error "cannot migrate 1GB file with limit"
8157                 echo "done"
8158
8159                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8160                 echo -n "Verifying 1GB autostripe count with limited space..."
8161                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8162                         error "unexpected stripe count $stripe_count (min 3)"
8163                 echo "done"
8164         fi
8165
8166         # clean up
8167         rm -rf $dir
8168 }
8169 run_test 56xc "lfs migration autostripe"
8170
8171 test_56xd() {
8172         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8173
8174         local dir=$DIR/$tdir
8175         local f_mgrt=$dir/$tfile.mgrt
8176         local f_yaml=$dir/$tfile.yaml
8177         local f_copy=$dir/$tfile.copy
8178         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8179         local layout_copy="-c 2 -S 2M -i 1"
8180         local yamlfile=$dir/yamlfile
8181         local layout_before;
8182         local layout_after;
8183
8184         test_mkdir "$dir" || error "cannot create dir $dir"
8185         stack_trap "rm -rf $dir"
8186         $LFS setstripe $layout_yaml $f_yaml ||
8187                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8188         $LFS getstripe --yaml $f_yaml > $yamlfile
8189         $LFS setstripe $layout_copy $f_copy ||
8190                 error "cannot setstripe $f_copy with layout $layout_copy"
8191         touch $f_mgrt
8192         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8193
8194         # 1. test option --yaml
8195         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8196                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8197         layout_before=$(get_layout_param $f_yaml)
8198         layout_after=$(get_layout_param $f_mgrt)
8199         [ "$layout_after" == "$layout_before" ] ||
8200                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8201
8202         # 2. test option --copy
8203         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8204                 error "cannot migrate $f_mgrt with --copy $f_copy"
8205         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8206         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8207         [ "$layout_after" == "$layout_before" ] ||
8208                 error "lfs_migrate --copy: $layout_after != $layout_before"
8209 }
8210 run_test 56xd "check lfs_migrate --yaml and --copy support"
8211
8212 test_56xe() {
8213         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8214
8215         local dir=$DIR/$tdir
8216         local f_comp=$dir/$tfile
8217         local layout="-E 1M -S 512K -E 2M -c 2 -E 3M -c 2 -E eof -c $OSTCOUNT"
8218         local layout_before=""
8219         local layout_after=""
8220
8221         test_mkdir "$dir" || error "cannot create dir $dir"
8222         stack_trap "rm -rf $dir"
8223         $LFS setstripe $layout $f_comp ||
8224                 error "cannot setstripe $f_comp with layout $layout"
8225         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8226         dd if=/dev/zero of=$f_comp bs=1M count=4
8227
8228         # 1. migrate a comp layout file by lfs_migrate
8229         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8230         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8231         idx_before=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8232                      tr '\n' ' ')
8233         [ "$layout_before" == "$layout_after" ] ||
8234                 error "lfs_migrate: $layout_before != $layout_after"
8235
8236         # 2. migrate a comp layout file by lfs migrate
8237         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8238         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8239         idx_after=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8240                      tr '\n' ' ')
8241         [ "$layout_before" == "$layout_after" ] ||
8242                 error "lfs migrate: $layout_before != $layout_after"
8243
8244         # this may not fail every time with a broken lfs migrate, but will fail
8245         # often enough to notice, and will not have false positives very often
8246         [ "$idx_before" != "$idx_after" ] ||
8247                 error "lfs migrate: $idx_before == $idx_after"
8248 }
8249 run_test 56xe "migrate a composite layout file"
8250
8251 test_56xf() {
8252         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8253
8254         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8255                 skip "Need server version at least 2.13.53"
8256
8257         local dir=$DIR/$tdir
8258         local f_comp=$dir/$tfile
8259         local layout="-E 1M -c1 -E -1 -c2"
8260         local fid_before=""
8261         local fid_after=""
8262
8263         test_mkdir "$dir" || error "cannot create dir $dir"
8264         stack_trap "rm -rf $dir"
8265         $LFS setstripe $layout $f_comp ||
8266                 error "cannot setstripe $f_comp with layout $layout"
8267         fid_before=$($LFS getstripe --fid $f_comp)
8268         dd if=/dev/zero of=$f_comp bs=1M count=4
8269
8270         # 1. migrate a comp layout file to a comp layout
8271         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8272         fid_after=$($LFS getstripe --fid $f_comp)
8273         [ "$fid_before" == "$fid_after" ] ||
8274                 error "comp-to-comp migrate: $fid_before != $fid_after"
8275
8276         # 2. migrate a comp layout file to a plain layout
8277         $LFS migrate -c2 $f_comp ||
8278                 error "cannot migrate $f_comp by lfs migrate"
8279         fid_after=$($LFS getstripe --fid $f_comp)
8280         [ "$fid_before" == "$fid_after" ] ||
8281                 error "comp-to-plain migrate: $fid_before != $fid_after"
8282
8283         # 3. migrate a plain layout file to a comp layout
8284         $LFS migrate $layout $f_comp ||
8285                 error "cannot migrate $f_comp by lfs migrate"
8286         fid_after=$($LFS getstripe --fid $f_comp)
8287         [ "$fid_before" == "$fid_after" ] ||
8288                 error "plain-to-comp migrate: $fid_before != $fid_after"
8289 }
8290 run_test 56xf "FID is not lost during migration of a composite layout file"
8291
8292 check_file_ost_range() {
8293         local file="$1"
8294         shift
8295         local range="$*"
8296         local -a file_range
8297         local idx
8298
8299         file_range=($($LFS getstripe -y "$file" |
8300                 awk '/l_ost_idx:/ { print $NF }'))
8301
8302         if [[ "${#file_range[@]}" = 0 ]]; then
8303                 echo "No osts found for $file"
8304                 return 1
8305         fi
8306
8307         for idx in "${file_range[@]}"; do
8308                 [[ " $range " =~ " $idx " ]] ||
8309                         return 1
8310         done
8311
8312         return 0
8313 }
8314
8315 sub_test_56xg() {
8316         local stripe_opt="$1"
8317         local pool="$2"
8318         shift 2
8319         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8320
8321         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8322                 error "Fail to migrate $tfile on $pool"
8323         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8324                 error "$tfile is not in pool $pool"
8325         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8326                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8327 }
8328
8329 test_56xg() {
8330         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8331         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8332         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8333                 skip "Need MDS version newer than 2.14.52"
8334
8335         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8336         local -a pool_ranges=("0 0" "1 1" "0 1")
8337
8338         # init pools
8339         for i in "${!pool_names[@]}"; do
8340                 pool_add ${pool_names[$i]} ||
8341                         error "pool_add failed (pool: ${pool_names[$i]})"
8342                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8343                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8344         done
8345
8346         # init the file to migrate
8347         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8348                 error "Unable to create $tfile on OST1"
8349         stack_trap "rm -f $DIR/$tfile"
8350         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8351                 error "Unable to write on $tfile"
8352
8353         echo "1. migrate $tfile on pool ${pool_names[0]}"
8354         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8355
8356         echo "2. migrate $tfile on pool ${pool_names[2]}"
8357         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8358
8359         echo "3. migrate $tfile on pool ${pool_names[1]}"
8360         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8361
8362         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8363         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8364         echo
8365
8366         # Clean pools
8367         destroy_test_pools ||
8368                 error "pool_destroy failed"
8369 }
8370 run_test 56xg "lfs migrate pool support"
8371
8372 test_56xh() {
8373         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8374
8375         local size_mb=25
8376         local file1=$DIR/$tfile
8377         local tmp1=$TMP/$tfile.tmp
8378
8379         $LFS setstripe -c 2 $file1
8380
8381         stack_trap "rm -f $file1 $tmp1"
8382         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8383                         error "error creating $tmp1"
8384         ls -lsh $tmp1
8385         cp $tmp1 $file1
8386
8387         local start=$SECONDS
8388
8389         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8390                 error "migrate failed rc = $?"
8391
8392         local elapsed=$((SECONDS - start))
8393
8394         # with 1MB/s, elapsed should equal size_mb
8395         (( elapsed >= size_mb * 95 / 100 )) ||
8396                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8397
8398         (( elapsed <= size_mb * 120 / 100 )) ||
8399                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8400
8401         (( elapsed <= size_mb * 350 / 100 )) ||
8402                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8403
8404         stripe=$($LFS getstripe -c $file1)
8405         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8406         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8407
8408         # Clean up file (since it is multiple MB)
8409         rm -f $file1 $tmp1
8410 }
8411 run_test 56xh "lfs migrate bandwidth limitation support"
8412
8413 test_56xi() {
8414         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8415         verify_yaml_available || skip_env "YAML verification not installed"
8416
8417         local size_mb=5
8418         local file1=$DIR/$tfile.1
8419         local file2=$DIR/$tfile.2
8420         local file3=$DIR/$tfile.3
8421         local output_file=$DIR/$tfile.out
8422         local tmp1=$TMP/$tfile.tmp
8423
8424         $LFS setstripe -c 2 $file1
8425         $LFS setstripe -c 2 $file2
8426         $LFS setstripe -c 2 $file3
8427
8428         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8429         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8430                         error "error creating $tmp1"
8431         ls -lsh $tmp1
8432         cp $tmp1 $file1
8433         cp $tmp1 $file2
8434         cp $tmp1 $file3
8435
8436         $LFS migrate --stats --stats-interval=1 \
8437                 -c 1 $file1 $file2 $file3 1> $output_file ||
8438                 error "migrate failed rc = $?"
8439
8440         cat $output_file
8441         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8442
8443         # Clean up file (since it is multiple MB)
8444         rm -f $file1 $file2 $file3 $tmp1 $output_file
8445 }
8446 run_test 56xi "lfs migrate stats support"
8447
8448 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8449         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8450
8451         local file=$DIR/$tfile
8452         local linkdir=$DIR/$tdir
8453
8454         test_mkdir $linkdir || error "fail to create $linkdir"
8455         $LFS setstripe -i 0 -c 1 -S1M $file
8456         stack_trap "rm -rf $file $linkdir"
8457         dd if=/dev/urandom of=$file bs=1M count=10 ||
8458                 error "fail to create $file"
8459
8460         # Create file links
8461         local cpts
8462         local threads_max
8463         local nlinks
8464
8465         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8466         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8467         (( nlinks = thread_max * 3 / 2 / cpts))
8468
8469         echo "create $nlinks hard links of $file"
8470         createmany -l $file $linkdir/link $nlinks
8471
8472         # Parallel migrates (should not block)
8473         local i
8474         for ((i = 0; i < nlinks; i++)); do
8475                 echo $linkdir/link$i
8476         done | xargs -n1 -P $nlinks $LFS migrate -c2
8477
8478         local stripe_count
8479         stripe_count=$($LFS getstripe -c $file) ||
8480                 error "fail to get stripe count on $file"
8481
8482         ((stripe_count == 2)) ||
8483                 error "fail to migrate $file (stripe_count = $stripe_count)"
8484 }
8485 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8486
8487 test_56xk() {
8488         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8489
8490         local size_mb=5
8491         local file1=$DIR/$tfile
8492
8493         stack_trap "rm -f $file1"
8494         $LFS setstripe -c 1 $file1
8495         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8496                 error "error creating $file1"
8497         $LFS mirror extend -N $file1 || error "can't mirror"
8498         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8499                 error "can't dd"
8500         $LFS getstripe $file1 | grep stale ||
8501                 error "one component must be stale"
8502
8503         local start=$SECONDS
8504         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8505                 error "migrate failed rc = $?"
8506         local elapsed=$((SECONDS - start))
8507         $LFS getstripe $file1 | grep stale &&
8508                 error "all components must be sync"
8509
8510         # with 1MB/s, elapsed should equal size_mb
8511         (( elapsed >= size_mb * 95 / 100 )) ||
8512                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8513
8514         (( elapsed <= size_mb * 120 / 100 )) ||
8515                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8516
8517         (( elapsed <= size_mb * 350 / 100 )) ||
8518                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8519 }
8520 run_test 56xk "lfs mirror resync bandwidth limitation support"
8521
8522 test_56xl() {
8523         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8524         verify_yaml_available || skip_env "YAML verification not installed"
8525
8526         local size_mb=5
8527         local file1=$DIR/$tfile.1
8528         local output_file=$DIR/$tfile.out
8529
8530         stack_trap "rm -f $file1"
8531         $LFS setstripe -c 1 $file1
8532         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8533                 error "error creating $file1"
8534         $LFS mirror extend -N $file1 || error "can't mirror"
8535         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8536                 error "can't dd"
8537         $LFS getstripe $file1 | grep stale ||
8538                 error "one component must be stale"
8539         $LFS getstripe $file1
8540
8541         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8542                 error "resync failed rc = $?"
8543         $LFS getstripe $file1 | grep stale &&
8544                 error "all components must be sync"
8545
8546         cat $output_file
8547         cat $output_file | verify_yaml || error "stats is not valid YAML"
8548 }
8549 run_test 56xl "lfs mirror resync stats support"
8550
8551 test_56y() {
8552         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8553                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8554
8555         local res=""
8556         local dir=$DIR/$tdir
8557         local f1=$dir/file1
8558         local f2=$dir/file2
8559
8560         test_mkdir -p $dir || error "creating dir $dir"
8561         touch $f1 || error "creating std file $f1"
8562         $MULTIOP $f2 H2c || error "creating released file $f2"
8563
8564         # a directory can be raid0, so ask only for files
8565         res=$($LFS find $dir -L raid0 -type f | wc -l)
8566         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8567
8568         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8569         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8570
8571         # only files can be released, so no need to force file search
8572         res=$($LFS find $dir -L released)
8573         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8574
8575         res=$($LFS find $dir -type f \! -L released)
8576         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8577 }
8578 run_test 56y "lfs find -L raid0|released"
8579
8580 test_56z() { # LU-4824
8581         # This checks to make sure 'lfs find' continues after errors
8582         # There are two classes of errors that should be caught:
8583         # - If multiple paths are provided, all should be searched even if one
8584         #   errors out
8585         # - If errors are encountered during the search, it should not terminate
8586         #   early
8587         local dir=$DIR/$tdir
8588         local i
8589
8590         test_mkdir $dir
8591         for i in d{0..9}; do
8592                 test_mkdir $dir/$i
8593                 touch $dir/$i/$tfile
8594         done
8595         $LFS find $DIR/non_existent_dir $dir &&
8596                 error "$LFS find did not return an error"
8597         # Make a directory unsearchable. This should NOT be the last entry in
8598         # directory order.  Arbitrarily pick the 6th entry
8599         chmod 700 $($LFS find $dir -type d | sed '6!d')
8600
8601         $RUNAS $LFS find $DIR/non_existent $dir
8602         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8603
8604         # The user should be able to see 10 directories and 9 files
8605         (( count == 19 )) ||
8606                 error "$LFS find found $count != 19 entries after error"
8607 }
8608 run_test 56z "lfs find should continue after an error"
8609
8610 test_56aa() { # LU-5937
8611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8612
8613         local dir=$DIR/$tdir
8614
8615         mkdir $dir
8616         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8617
8618         createmany -o $dir/striped_dir/${tfile}- 1024
8619         local dirs=$($LFS find --size +8k $dir/)
8620
8621         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8622 }
8623 run_test 56aa "lfs find --size under striped dir"
8624
8625 test_56ab() { # LU-10705
8626         test_mkdir $DIR/$tdir
8627         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8628         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8629         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8630         # Flush writes to ensure valid blocks.  Need to be more thorough for
8631         # ZFS, since blocks are not allocated/returned to client immediately.
8632         sync_all_data
8633         wait_zfs_commit ost1 2
8634         cancel_lru_locks osc
8635         ls -ls $DIR/$tdir
8636
8637         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8638
8639         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8640
8641         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8642         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8643
8644         rm -f $DIR/$tdir/$tfile.[123]
8645 }
8646 run_test 56ab "lfs find --blocks"
8647
8648 # LU-11188
8649 test_56aca() {
8650         local dir="$DIR/$tdir"
8651         local perms=(001 002 003 004 005 006 007
8652                      010 020 030 040 050 060 070
8653                      100 200 300 400 500 600 700
8654                      111 222 333 444 555 666 777)
8655         local perm_minus=(8 8 4 8 4 4 2
8656                           8 8 4 8 4 4 2
8657                           8 8 4 8 4 4 2
8658                           4 4 2 4 2 2 1)
8659         local perm_slash=(8  8 12  8 12 12 14
8660                           8  8 12  8 12 12 14
8661                           8  8 12  8 12 12 14
8662                          16 16 24 16 24 24 28)
8663
8664         test_mkdir "$dir"
8665         for perm in ${perms[*]}; do
8666                 touch "$dir/$tfile.$perm"
8667                 chmod $perm "$dir/$tfile.$perm"
8668         done
8669
8670         for ((i = 0; i < ${#perms[*]}; i++)); do
8671                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8672                 (( $num == 1 )) ||
8673                         error "lfs find -perm ${perms[i]}:"\
8674                               "$num != 1"
8675
8676                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8677                 (( $num == ${perm_minus[i]} )) ||
8678                         error "lfs find -perm -${perms[i]}:"\
8679                               "$num != ${perm_minus[i]}"
8680
8681                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8682                 (( $num == ${perm_slash[i]} )) ||
8683                         error "lfs find -perm /${perms[i]}:"\
8684                               "$num != ${perm_slash[i]}"
8685         done
8686 }
8687 run_test 56aca "check lfs find -perm with octal representation"
8688
8689 test_56acb() {
8690         local dir=$DIR/$tdir
8691         # p is the permission of write and execute for user, group and other
8692         # without the umask. It is used to test +wx.
8693         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8694         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8695         local symbolic=(+t  a+t u+t g+t o+t
8696                         g+s u+s o+s +s o+sr
8697                         o=r,ug+o,u+w
8698                         u+ g+ o+ a+ ugo+
8699                         u- g- o- a- ugo-
8700                         u= g= o= a= ugo=
8701                         o=r,ug+o,u+w u=r,a+u,u+w
8702                         g=r,ugo=g,u+w u+x,+X +X
8703                         u+x,u+X u+X u+x,g+X o+r,+X
8704                         u+x,go+X +wx +rwx)
8705
8706         test_mkdir $dir
8707         for perm in ${perms[*]}; do
8708                 touch "$dir/$tfile.$perm"
8709                 chmod $perm "$dir/$tfile.$perm"
8710         done
8711
8712         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8713                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8714
8715                 (( $num == 1 )) ||
8716                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8717         done
8718 }
8719 run_test 56acb "check lfs find -perm with symbolic representation"
8720
8721 test_56acc() {
8722         local dir=$DIR/$tdir
8723         local tests="17777 787 789 abcd
8724                 ug=uu ug=a ug=gu uo=ou urw
8725                 u+xg+x a=r,u+x,"
8726
8727         test_mkdir $dir
8728         for err in $tests; do
8729                 if $LFS find $dir -perm $err 2>/dev/null; then
8730                         error "lfs find -perm $err: parsing should have failed"
8731                 fi
8732         done
8733 }
8734 run_test 56acc "check parsing error for lfs find -perm"
8735
8736 test_56ba() {
8737         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8738                 skip "Need MDS version at least 2.10.50"
8739
8740         # Create composite files with one component
8741         local dir=$DIR/$tdir
8742
8743         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8744         # Create composite files with three components
8745         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8746         # LU-16904 Create plain layout files
8747         lfs setstripe -c 1 $dir/$tfile-{1..10}
8748
8749         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8750
8751         [[ $nfiles == 10 ]] ||
8752                 error "lfs find -E 1M found $nfiles != 10 files"
8753
8754         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8755         [[ $nfiles == 25 ]] ||
8756                 error "lfs find ! -E 1M found $nfiles != 25 files"
8757
8758         # All files have a component that starts at 0
8759         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8760         [[ $nfiles == 35 ]] ||
8761                 error "lfs find --component-start 0 - $nfiles != 35 files"
8762
8763         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8764         [[ $nfiles == 15 ]] ||
8765                 error "lfs find --component-start 2M - $nfiles != 15 files"
8766
8767         # All files created here have a componenet that does not starts at 2M
8768         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8769         [[ $nfiles == 35 ]] ||
8770                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8771
8772         # Find files with a specified number of components
8773         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8774         [[ $nfiles == 15 ]] ||
8775                 error "lfs find --component-count 3 - $nfiles != 15 files"
8776
8777         # Remember non-composite files have a component count of zero
8778         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8779         [[ $nfiles == 10 ]] ||
8780                 error "lfs find --component-count 0 - $nfiles != 10 files"
8781
8782         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8783         [[ $nfiles == 20 ]] ||
8784                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8785
8786         # All files have a flag called "init"
8787         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8788         [[ $nfiles == 35 ]] ||
8789                 error "lfs find --component-flags init - $nfiles != 35 files"
8790
8791         # Multi-component files will have a component not initialized
8792         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8793         [[ $nfiles == 15 ]] ||
8794                 error "lfs find !--component-flags init - $nfiles != 15 files"
8795
8796         rm -rf $dir
8797
8798 }
8799 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8800
8801 test_56ca() {
8802         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8803                 skip "Need MDS version at least 2.10.57"
8804
8805         local td=$DIR/$tdir
8806         local tf=$td/$tfile
8807         local dir
8808         local nfiles
8809         local cmd
8810         local i
8811         local j
8812
8813         # create mirrored directories and mirrored files
8814         mkdir $td || error "mkdir $td failed"
8815         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8816         createmany -o $tf- 10 || error "create $tf- failed"
8817
8818         for i in $(seq 2); do
8819                 dir=$td/dir$i
8820                 mkdir $dir || error "mkdir $dir failed"
8821                 $LFS mirror create -N$((3 + i)) $dir ||
8822                         error "create mirrored dir $dir failed"
8823                 createmany -o $dir/$tfile- 10 ||
8824                         error "create $dir/$tfile- failed"
8825         done
8826
8827         # change the states of some mirrored files
8828         echo foo > $tf-6
8829         for i in $(seq 2); do
8830                 dir=$td/dir$i
8831                 for j in $(seq 4 9); do
8832                         echo foo > $dir/$tfile-$j
8833                 done
8834         done
8835
8836         # find mirrored files with specific mirror count
8837         cmd="$LFS find --mirror-count 3 --type f $td"
8838         nfiles=$($cmd | wc -l)
8839         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8840
8841         cmd="$LFS find ! --mirror-count 3 --type f $td"
8842         nfiles=$($cmd | wc -l)
8843         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8844
8845         cmd="$LFS find --mirror-count +2 --type f $td"
8846         nfiles=$($cmd | wc -l)
8847         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8848
8849         cmd="$LFS find --mirror-count -6 --type f $td"
8850         nfiles=$($cmd | wc -l)
8851         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8852
8853         # find mirrored files with specific file state
8854         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8855         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8856
8857         cmd="$LFS find --mirror-state=ro --type f $td"
8858         nfiles=$($cmd | wc -l)
8859         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8860
8861         cmd="$LFS find ! --mirror-state=ro --type f $td"
8862         nfiles=$($cmd | wc -l)
8863         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8864
8865         cmd="$LFS find --mirror-state=wp --type f $td"
8866         nfiles=$($cmd | wc -l)
8867         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8868
8869         cmd="$LFS find ! --mirror-state=sp --type f $td"
8870         nfiles=$($cmd | wc -l)
8871         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8872 }
8873 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8874
8875 test_56da() { # LU-14179
8876         local path=$DIR/$tdir
8877
8878         test_mkdir $path
8879         cd $path
8880
8881         local longdir=$(str_repeat 'a' 255)
8882
8883         for i in {1..15}; do
8884                 path=$path/$longdir
8885                 test_mkdir $longdir
8886                 cd $longdir
8887         done
8888
8889         local len=${#path}
8890         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8891
8892         test_mkdir $lastdir
8893         cd $lastdir
8894         # PATH_MAX-1
8895         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8896
8897         # NAME_MAX
8898         touch $(str_repeat 'f' 255)
8899
8900         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8901                 error "lfs find reported an error"
8902
8903         rm -rf $DIR/$tdir
8904 }
8905 run_test 56da "test lfs find with long paths"
8906
8907 test_56ea() { #LU-10378
8908         local path=$DIR/$tdir
8909         local pool=$TESTNAME
8910
8911         # Create ost pool
8912         pool_add $pool || error "pool_add $pool failed"
8913         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8914                 error "adding targets to $pool failed"
8915
8916         # Set default pool on directory before creating file
8917         mkdir $path || error "mkdir $path failed"
8918         $LFS setstripe -p $pool $path ||
8919                 error "set OST pool on $pool failed"
8920         touch $path/$tfile || error "touch $path/$tfile failed"
8921
8922         # Compare basic file attributes from -printf and stat
8923         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8924         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8925
8926         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8927                 error "Attrs from lfs find and stat don't match"
8928
8929         # Compare Lustre attributes from lfs find and lfs getstripe
8930         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8931         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8932         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8933         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8934         local fpool=$($LFS getstripe --pool $path/$tfile)
8935         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8936
8937         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8938                 error "Attrs from lfs find and lfs getstripe don't match"
8939
8940         # Verify behavior for unknown escape/format sequences
8941         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8942
8943         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8944                 error "Escape/format codes don't match"
8945 }
8946 run_test 56ea "test lfs find -printf option"
8947
8948 test_56eb() {
8949         local dir=$DIR/$tdir
8950         local subdir_1=$dir/subdir_1
8951
8952         test_mkdir -p $subdir_1
8953         ln -s subdir_1 $dir/link_1
8954
8955         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8956                 error "symlink is not followed"
8957
8958         $LFS getstripe --no-follow $dir |
8959                 grep "^$dir/link_1 has no stripe info$" ||
8960                 error "symlink should not have stripe info"
8961
8962         touch $dir/testfile
8963         ln -s testfile $dir/file_link_2
8964
8965         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8966                 error "symlink is not followed"
8967
8968         $LFS getstripe --no-follow $dir |
8969                 grep "^$dir/file_link_2 has no stripe info$" ||
8970                 error "symlink should not have stripe info"
8971 }
8972 run_test 56eb "check lfs getstripe on symlink"
8973
8974 test_56ec() {
8975         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8976         local dir=$DIR/$tdir
8977         local srcfile=$dir/srcfile
8978         local srcyaml=$dir/srcyaml
8979         local destfile=$dir/destfile
8980
8981         test_mkdir -p $dir
8982
8983         $LFS setstripe -i 1 $srcfile
8984         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8985         # if the setstripe yaml parsing fails for any reason, the command can
8986         # randomly assign the correct OST index, leading to an erroneous
8987         # success. but the chance of false success is low enough that a
8988         # regression should still be quickly caught.
8989         $LFS setstripe --yaml=$srcyaml $destfile
8990
8991         local srcindex=$($LFS getstripe -i $srcfile)
8992         local destindex=$($LFS getstripe -i $destfile)
8993
8994         if [[ ! $srcindex -eq $destindex ]]; then
8995                 error "setstripe did not set OST index correctly"
8996         fi
8997 }
8998 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8999
9000 test_56eda() {
9001         local dir=$DIR/$tdir
9002         local subdir=$dir/subdir
9003         local file1=$dir/$tfile
9004         local file2=$dir/$tfile\2
9005         local link=$dir/$tfile-link
9006         local nfiles
9007
9008         test_mkdir -p $dir
9009         $LFS setdirstripe -c1 $subdir
9010         touch $file1
9011         touch $file2
9012         ln $file2 $link
9013
9014         nfiles=$($LFS find --links 1 $dir | wc -l)
9015         (( $nfiles == 1 )) ||
9016                 error "lfs find --links expected 1 file, got $nfiles"
9017
9018         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
9019         (( $nfiles == 2 )) ||
9020                 error "lfs find --links expected 2 files, got $nfiles"
9021
9022         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
9023         (( $nfiles == 1 )) ||
9024                 error "lfs find --links expected 1 directory, got $nfiles"
9025 }
9026 run_test 56eda "check lfs find --links"
9027
9028 test_56edb() {
9029         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9030
9031         local dir=$DIR/$tdir
9032         local stripedir=$dir/stripedir
9033         local nfiles
9034
9035         test_mkdir -p $dir
9036
9037         $LFS setdirstripe -c2 $stripedir
9038
9039         $LFS getdirstripe $stripedir
9040
9041         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9042         (( $nfiles == 1 )) ||
9043                 error "lfs find --links expected 1 directory, got $nfiles"
9044 }
9045 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9046
9047 test_56ef() {
9048         local dir=$DIR/$tdir
9049         local dir1=$dir/d1
9050         local dir2=$dir/d2
9051         local nfiles
9052         local err_msg
9053
9054         test_mkdir -p $dir
9055
9056         mkdir $dir1
9057         mkdir $dir2
9058
9059         touch $dir1/f
9060         touch $dir2/f
9061
9062         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9063         (( $nfiles == 2 )) ||
9064                 error "(1) lfs find expected 2 files, got $nfiles"
9065
9066         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9067         (( $nfiles == 2 )) ||
9068                 error "(2) lfs find expected 2 files, got $nfiles"
9069
9070         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9071         (( $nfiles == 2 )) ||
9072                 error "(3) lfs find expected 2 files, got $nfiles"
9073
9074         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9075         [[ $err_msg =~ "No such file or directory" ]] ||
9076                 error "expected standard error message, got: '$err_msg'"
9077 }
9078 run_test 56ef "lfs find with multiple paths"
9079
9080 test_56eg() {
9081         local dir=$DIR/$tdir
9082         local found
9083
9084         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9085
9086         test_mkdir -p $dir
9087
9088         touch $dir/$tfile
9089         ln -s $dir/$tfile $dir/$tfile.symlink
9090         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9091         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9092                 $dir/$tfile.symlink
9093         setfattr --no-dereference -n "trusted.common" \
9094                 $dir/{$tfile,$tfile.symlink}
9095
9096         found=$($LFS find -xattr "trusted.*=test_target" \
9097                 -xattr "trusted.common" $dir)
9098         [[ "$found" == "$dir/$tfile" ]] || {
9099                 getfattr -d -m trusted.* $dir/$tfile
9100                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9101         }
9102
9103         found=$($LFS find -xattr "trusted.*=test_link" \
9104                 -xattr "trusted.common" $dir)
9105         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9106                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9107                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9108         }
9109
9110         rm -f $dir/*
9111
9112         touch $dir/$tfile.1
9113         touch $dir/$tfile.2
9114         setfattr -n "user.test" -v "1" $dir/$tfile.1
9115         setfattr -n "user.test" -v "2" $dir/$tfile.2
9116         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9117
9118         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9119         [[ "$found" == "$dir/$tfile.1" ]] || {
9120                 getfattr -d $dir/$tfile.1
9121                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9122         }
9123
9124         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9125         [[ "$found" == "$dir/$tfile.2" ]] || {
9126                 getfattr -d $dir/$tfile.2
9127                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9128         }
9129
9130         setfattr -n "user.empty" $dir/$tfile.1
9131         found=$($LFS find -xattr "user.empty" $dir)
9132         [[ "$found" == "$dir/$tfile.1" ]] || {
9133                 getfattr -d $dir/$tfile.1
9134                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9135         }
9136
9137         # setfattr command normally does not store terminating null byte
9138         # when writing a string as an xattr value.
9139         #
9140         # In order to test matching a value string that includes a terminating
9141         # null, explicitly encode the string "test\0" with the null terminator.
9142         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9143         found=$($LFS find -xattr "user.test=test" $dir)
9144         [[ "$found" == "$dir/$tfile.1" ]] || {
9145                 getfattr -d --encoding=hex $dir/$tfile.1
9146                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9147         }
9148 }
9149 run_test 56eg "lfs find -xattr"
9150
9151 test_57a() {
9152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9153         # note test will not do anything if MDS is not local
9154         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9155                 skip_env "ldiskfs only test"
9156         fi
9157         remote_mds_nodsh && skip "remote MDS with nodsh"
9158
9159         local MNTDEV="osd*.*MDT*.mntdev"
9160         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9161         [ -z "$DEV" ] && error "can't access $MNTDEV"
9162         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9163                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9164                         error "can't access $DEV"
9165                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9166                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9167                 rm $TMP/t57a.dump
9168         done
9169 }
9170 run_test 57a "verify MDS filesystem created with large inodes =="
9171
9172 test_57b() {
9173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9174         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9175                 skip_env "ldiskfs only test"
9176         fi
9177         remote_mds_nodsh && skip "remote MDS with nodsh"
9178
9179         local dir=$DIR/$tdir
9180         local filecount=100
9181         local file1=$dir/f1
9182         local fileN=$dir/f$filecount
9183
9184         rm -rf $dir || error "removing $dir"
9185         test_mkdir -c1 $dir
9186         local mdtidx=$($LFS getstripe -m $dir)
9187         local mdtname=MDT$(printf %04x $mdtidx)
9188         local facet=mds$((mdtidx + 1))
9189
9190         echo "mcreating $filecount files"
9191         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9192
9193         # verify that files do not have EAs yet
9194         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9195                 error "$file1 has an EA"
9196         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9197                 error "$fileN has an EA"
9198
9199         sync
9200         sleep 1
9201         df $dir  #make sure we get new statfs data
9202         local mdsfree=$(do_facet $facet \
9203                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9204         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9205         local file
9206
9207         echo "opening files to create objects/EAs"
9208         for file in $(seq -f $dir/f%g 1 $filecount); do
9209                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9210                         error "opening $file"
9211         done
9212
9213         # verify that files have EAs now
9214         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9215                 error "$file1 missing EA"
9216         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9217                 error "$fileN missing EA"
9218
9219         sleep 1  #make sure we get new statfs data
9220         df $dir
9221         local mdsfree2=$(do_facet $facet \
9222                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9223         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9224
9225         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9226                 if [ "$mdsfree" != "$mdsfree2" ]; then
9227                         error "MDC before $mdcfree != after $mdcfree2"
9228                 else
9229                         echo "MDC before $mdcfree != after $mdcfree2"
9230                         echo "unable to confirm if MDS has large inodes"
9231                 fi
9232         fi
9233         rm -rf $dir
9234 }
9235 run_test 57b "default LOV EAs are stored inside large inodes ==="
9236
9237 test_58() {
9238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9239         [ -z "$(which wiretest 2>/dev/null)" ] &&
9240                         skip_env "could not find wiretest"
9241
9242         wiretest
9243 }
9244 run_test 58 "verify cross-platform wire constants =============="
9245
9246 test_59() {
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248
9249         echo "touch 130 files"
9250         createmany -o $DIR/f59- 130
9251         echo "rm 130 files"
9252         unlinkmany $DIR/f59- 130
9253         sync
9254         # wait for commitment of removal
9255         wait_delete_completed
9256 }
9257 run_test 59 "verify cancellation of llog records async ========="
9258
9259 TEST60_HEAD="test_60 run $RANDOM"
9260 test_60a() {
9261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9262         remote_mgs_nodsh && skip "remote MGS with nodsh"
9263         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9264                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9265                         skip_env "missing subtest run-llog.sh"
9266
9267         log "$TEST60_HEAD - from kernel mode"
9268         do_facet mgs "$LCTL dk > /dev/null"
9269         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9270         do_facet mgs $LCTL dk > $TMP/$tfile
9271
9272         # LU-6388: test llog_reader
9273         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9274         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9275         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9276                         skip_env "missing llog_reader"
9277         local fstype=$(facet_fstype mgs)
9278         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9279                 skip_env "Only for ldiskfs or zfs type mgs"
9280
9281         local mntpt=$(facet_mntpt mgs)
9282         local mgsdev=$(mgsdevname 1)
9283         local fid_list
9284         local fid
9285         local rec_list
9286         local rec
9287         local rec_type
9288         local obj_file
9289         local path
9290         local seq
9291         local oid
9292         local pass=true
9293
9294         #get fid and record list
9295         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9296                 tail -n 4))
9297         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9298                 tail -n 4))
9299         #remount mgs as ldiskfs or zfs type
9300         stop mgs || error "stop mgs failed"
9301         mount_fstype mgs || error "remount mgs failed"
9302         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9303                 fid=${fid_list[i]}
9304                 rec=${rec_list[i]}
9305                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9306                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9307                 oid=$((16#$oid))
9308
9309                 case $fstype in
9310                         ldiskfs )
9311                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9312                         zfs )
9313                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9314                 esac
9315                 echo "obj_file is $obj_file"
9316                 do_facet mgs $llog_reader $obj_file
9317
9318                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9319                         awk '{ print $3 }' | sed -e "s/^type=//g")
9320                 if [ $rec_type != $rec ]; then
9321                         echo "FAILED test_60a wrong record type $rec_type," \
9322                               "should be $rec"
9323                         pass=false
9324                         break
9325                 fi
9326
9327                 #check obj path if record type is LLOG_LOGID_MAGIC
9328                 if [ "$rec" == "1064553b" ]; then
9329                         path=$(do_facet mgs $llog_reader $obj_file |
9330                                 grep "path=" | awk '{ print $NF }' |
9331                                 sed -e "s/^path=//g")
9332                         if [ $obj_file != $mntpt/$path ]; then
9333                                 echo "FAILED test_60a wrong obj path" \
9334                                       "$montpt/$path, should be $obj_file"
9335                                 pass=false
9336                                 break
9337                         fi
9338                 fi
9339         done
9340         rm -f $TMP/$tfile
9341         #restart mgs before "error", otherwise it will block the next test
9342         stop mgs || error "stop mgs failed"
9343         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9344         $pass || error "test failed, see FAILED test_60a messages for specifics"
9345 }
9346 run_test 60a "llog_test run from kernel module and test llog_reader"
9347
9348 test_60b() { # bug 6411
9349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9350
9351         dmesg > $DIR/$tfile
9352         LLOG_COUNT=$(do_facet mgs dmesg |
9353                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9354                           /llog_[a-z]*.c:[0-9]/ {
9355                                 if (marker)
9356                                         from_marker++
9357                                 from_begin++
9358                           }
9359                           END {
9360                                 if (marker)
9361                                         print from_marker
9362                                 else
9363                                         print from_begin
9364                           }")
9365
9366         [[ $LLOG_COUNT -gt 120 ]] &&
9367                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9368 }
9369 run_test 60b "limit repeated messages from CERROR/CWARN"
9370
9371 test_60c() {
9372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9373
9374         echo "create 5000 files"
9375         createmany -o $DIR/f60c- 5000
9376 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9377         lctl set_param fail_loc=0x80000137
9378         unlinkmany $DIR/f60c- 5000
9379         lctl set_param fail_loc=0
9380 }
9381 run_test 60c "unlink file when mds full"
9382
9383 test_60d() {
9384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9385
9386         SAVEPRINTK=$(lctl get_param -n printk)
9387         # verify "lctl mark" is even working"
9388         MESSAGE="test message ID $RANDOM $$"
9389         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9390         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9391
9392         lctl set_param printk=0 || error "set lnet.printk failed"
9393         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9394         MESSAGE="new test message ID $RANDOM $$"
9395         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9396         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9397         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9398
9399         lctl set_param -n printk="$SAVEPRINTK"
9400 }
9401 run_test 60d "test printk console message masking"
9402
9403 test_60e() {
9404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9405         remote_mds_nodsh && skip "remote MDS with nodsh"
9406
9407         touch $DIR/$tfile
9408 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9409         do_facet mds1 lctl set_param fail_loc=0x15b
9410         rm $DIR/$tfile
9411 }
9412 run_test 60e "no space while new llog is being created"
9413
9414 test_60f() {
9415         local old_path=$($LCTL get_param -n debug_path)
9416
9417         stack_trap "$LCTL set_param debug_path=$old_path"
9418         stack_trap "rm -f $TMP/$tfile*"
9419         rm -f $TMP/$tfile* 2> /dev/null
9420         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9421         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9422         test_mkdir $DIR/$tdir
9423         # retry in case the open is cached and not released
9424         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9425                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9426                 sleep 0.1
9427         done
9428         ls $TMP/$tfile*
9429         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9430 }
9431 run_test 60f "change debug_path works"
9432
9433 test_60g() {
9434         local pid
9435         local i
9436
9437         test_mkdir -c $MDSCOUNT $DIR/$tdir
9438
9439         (
9440                 local index=0
9441                 while true; do
9442                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9443                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9444                                 2>/dev/null
9445                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9446                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9447                         index=$((index + 1))
9448                 done
9449         ) &
9450
9451         pid=$!
9452
9453         for i in {0..100}; do
9454                 # define OBD_FAIL_OSD_TXN_START    0x19a
9455                 local index=$((i % MDSCOUNT + 1))
9456
9457                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9458                         > /dev/null
9459                 sleep 0.01
9460         done
9461
9462         kill -9 $pid
9463
9464         for i in $(seq $MDSCOUNT); do
9465                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9466         done
9467
9468         mkdir $DIR/$tdir/new || error "mkdir failed"
9469         rmdir $DIR/$tdir/new || error "rmdir failed"
9470
9471         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9472                 -t namespace
9473         for i in $(seq $MDSCOUNT); do
9474                 wait_update_facet mds$i "$LCTL get_param -n \
9475                         mdd.$(facet_svc mds$i).lfsck_namespace |
9476                         awk '/^status/ { print \\\$2 }'" "completed"
9477         done
9478
9479         ls -R $DIR/$tdir
9480         rm -rf $DIR/$tdir || error "rmdir failed"
9481 }
9482 run_test 60g "transaction abort won't cause MDT hung"
9483
9484 test_60h() {
9485         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9486                 skip "Need MDS version at least 2.12.52"
9487         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9488
9489         local f
9490
9491         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9492         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9493         for fail_loc in 0x80000188 0x80000189; do
9494                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9495                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9496                         error "mkdir $dir-$fail_loc failed"
9497                 for i in {0..10}; do
9498                         # create may fail on missing stripe
9499                         echo $i > $DIR/$tdir-$fail_loc/$i
9500                 done
9501                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9502                         error "getdirstripe $tdir-$fail_loc failed"
9503                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9504                         error "migrate $tdir-$fail_loc failed"
9505                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9506                         error "getdirstripe $tdir-$fail_loc failed"
9507                 pushd $DIR/$tdir-$fail_loc
9508                 for f in *; do
9509                         echo $f | cmp $f - || error "$f data mismatch"
9510                 done
9511                 popd
9512                 rm -rf $DIR/$tdir-$fail_loc
9513         done
9514 }
9515 run_test 60h "striped directory with missing stripes can be accessed"
9516
9517 function t60i_load() {
9518         mkdir $DIR/$tdir
9519         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9520         $LCTL set_param fail_loc=0x131c fail_val=1
9521         for ((i=0; i<5000; i++)); do
9522                 touch $DIR/$tdir/f$i
9523         done
9524 }
9525
9526 test_60i() {
9527         changelog_register || error "changelog_register failed"
9528         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9529         changelog_users $SINGLEMDS | grep -q $cl_user ||
9530                 error "User $cl_user not found in changelog_users"
9531         changelog_chmask "ALL"
9532         t60i_load &
9533         local PID=$!
9534         for((i=0; i<100; i++)); do
9535                 changelog_dump >/dev/null ||
9536                         error "can't read changelog"
9537         done
9538         kill $PID
9539         wait $PID
9540         changelog_deregister || error "changelog_deregister failed"
9541         $LCTL set_param fail_loc=0
9542 }
9543 run_test 60i "llog: new record vs reader race"
9544
9545 test_60j() {
9546         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9547                 skip "need MDS version at least 2.15.50"
9548         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9549         remote_mds_nodsh && skip "remote MDS with nodsh"
9550         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9551
9552         changelog_users $SINGLEMDS | grep "^cl" &&
9553                 skip "active changelog user"
9554
9555         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9556
9557         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9558                 skip_env "missing llog_reader"
9559
9560         mkdir_on_mdt0 $DIR/$tdir
9561
9562         local f=$DIR/$tdir/$tfile
9563         local mdt_dev
9564         local tmpfile
9565         local plain
9566
9567         changelog_register || error "cannot register changelog user"
9568
9569         # set changelog_mask to ALL
9570         changelog_chmask "ALL"
9571         changelog_clear
9572
9573         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9574         unlinkmany ${f}- 100 || error "unlinkmany failed"
9575
9576         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9577         mdt_dev=$(facet_device $SINGLEMDS)
9578
9579         do_facet $SINGLEMDS sync
9580         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9581                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9582                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9583
9584         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9585
9586         # if $tmpfile is not on EXT3 filesystem for some reason
9587         [[ ${plain:0:1} == 'O' ]] ||
9588                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9589
9590         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9591                 $mdt_dev; stat -c %s $tmpfile")
9592         echo "Truncate llog from $size to $((size - size % 8192))"
9593         size=$((size - size % 8192))
9594         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9595         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9596                 grep -c 'in bitmap only')
9597         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9598
9599         size=$((size - 9000))
9600         echo "Corrupt llog in the middle at $size"
9601         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9602                 count=333 conv=notrunc
9603         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9604                 grep -c 'next chunk')
9605         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9606 }
9607 run_test 60j "llog_reader reports corruptions"
9608
9609 test_61a() {
9610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9611
9612         f="$DIR/f61"
9613         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9614         cancel_lru_locks osc
9615         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9616         sync
9617 }
9618 run_test 61a "mmap() writes don't make sync hang ================"
9619
9620 test_61b() {
9621         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9622 }
9623 run_test 61b "mmap() of unstriped file is successful"
9624
9625 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9626 # Though this test is irrelevant anymore, it helped to reveal some
9627 # other grant bugs (LU-4482), let's keep it.
9628 test_63a() {   # was test_63
9629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9630
9631         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9632
9633         for i in `seq 10` ; do
9634                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9635                 sleep 5
9636                 kill $!
9637                 sleep 1
9638         done
9639
9640         rm -f $DIR/f63 || true
9641 }
9642 run_test 63a "Verify oig_wait interruption does not crash ======="
9643
9644 # bug 2248 - async write errors didn't return to application on sync
9645 # bug 3677 - async write errors left page locked
9646 test_63b() {
9647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9648
9649         debugsave
9650         lctl set_param debug=-1
9651
9652         # ensure we have a grant to do async writes
9653         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9654         rm $DIR/$tfile
9655
9656         sync    # sync lest earlier test intercept the fail_loc
9657
9658         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9659         lctl set_param fail_loc=0x80000406
9660         $MULTIOP $DIR/$tfile Owy && \
9661                 error "sync didn't return ENOMEM"
9662         sync; sleep 2; sync     # do a real sync this time to flush page
9663         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9664                 error "locked page left in cache after async error" || true
9665         debugrestore
9666 }
9667 run_test 63b "async write errors should be returned to fsync ==="
9668
9669 test_64a () {
9670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9671
9672         lfs df $DIR
9673         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9674 }
9675 run_test 64a "verify filter grant calculations (in kernel) ====="
9676
9677 test_64b () {
9678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9679
9680         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9681 }
9682 run_test 64b "check out-of-space detection on client"
9683
9684 test_64c() {
9685         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9686 }
9687 run_test 64c "verify grant shrink"
9688
9689 import_param() {
9690         local tgt=$1
9691         local param=$2
9692
9693         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9694 }
9695
9696 # this does exactly what osc_request.c:osc_announce_cached() does in
9697 # order to calculate max amount of grants to ask from server
9698 want_grant() {
9699         local tgt=$1
9700
9701         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9702         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9703
9704         ((rpc_in_flight++));
9705         nrpages=$((nrpages * rpc_in_flight))
9706
9707         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9708
9709         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9710
9711         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9712         local undirty=$((nrpages * PAGE_SIZE))
9713
9714         local max_extent_pages
9715         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9716         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9717         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9718         local grant_extent_tax
9719         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9720
9721         undirty=$((undirty + nrextents * grant_extent_tax))
9722
9723         echo $undirty
9724 }
9725
9726 # this is size of unit for grant allocation. It should be equal to
9727 # what tgt_grant.c:tgt_grant_chunk() calculates
9728 grant_chunk() {
9729         local tgt=$1
9730         local max_brw_size
9731         local grant_extent_tax
9732
9733         max_brw_size=$(import_param $tgt max_brw_size)
9734
9735         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9736
9737         echo $(((max_brw_size + grant_extent_tax) * 2))
9738 }
9739
9740 test_64d() {
9741         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9742                 skip "OST < 2.10.55 doesn't limit grants enough"
9743
9744         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9745
9746         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9747                 skip "no grant_param connect flag"
9748
9749         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9750
9751         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9752         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9753
9754
9755         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9756         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9757
9758         $LFS setstripe $DIR/$tfile -i 0 -c 1
9759         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9760         ddpid=$!
9761
9762         while kill -0 $ddpid; do
9763                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9764
9765                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9766                         kill $ddpid
9767                         error "cur_grant $cur_grant > $max_cur_granted"
9768                 fi
9769
9770                 sleep 1
9771         done
9772 }
9773 run_test 64d "check grant limit exceed"
9774
9775 check_grants() {
9776         local tgt=$1
9777         local expected=$2
9778         local msg=$3
9779         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9780
9781         ((cur_grants == expected)) ||
9782                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9783 }
9784
9785 round_up_p2() {
9786         echo $((($1 + $2 - 1) & ~($2 - 1)))
9787 }
9788
9789 test_64e() {
9790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9791         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9792                 skip "Need OSS version at least 2.11.56"
9793
9794         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9795         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9796         $LCTL set_param debug=+cache
9797
9798         # Remount client to reset grant
9799         remount_client $MOUNT || error "failed to remount client"
9800         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9801
9802         local init_grants=$(import_param $osc_tgt initial_grant)
9803
9804         check_grants $osc_tgt $init_grants "init grants"
9805
9806         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9807         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9808         local gbs=$(import_param $osc_tgt grant_block_size)
9809
9810         # write random number of bytes from max_brw_size / 4 to max_brw_size
9811         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9812         # align for direct io
9813         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9814         # round to grant consumption unit
9815         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9816
9817         local grants=$((wb_round_up + extent_tax))
9818
9819         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9820         stack_trap "rm -f $DIR/$tfile"
9821
9822         # define OBD_FAIL_TGT_NO_GRANT 0x725
9823         # make the server not grant more back
9824         do_facet ost1 $LCTL set_param fail_loc=0x725
9825         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9826
9827         do_facet ost1 $LCTL set_param fail_loc=0
9828
9829         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9830
9831         rm -f $DIR/$tfile || error "rm failed"
9832
9833         # Remount client to reset grant
9834         remount_client $MOUNT || error "failed to remount client"
9835         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9836
9837         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9838
9839         # define OBD_FAIL_TGT_NO_GRANT 0x725
9840         # make the server not grant more back
9841         do_facet ost1 $LCTL set_param fail_loc=0x725
9842         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9843         do_facet ost1 $LCTL set_param fail_loc=0
9844
9845         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9846 }
9847 run_test 64e "check grant consumption (no grant allocation)"
9848
9849 test_64f() {
9850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9851
9852         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9853         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9854         $LCTL set_param debug=+cache
9855
9856         # Remount client to reset grant
9857         remount_client $MOUNT || error "failed to remount client"
9858         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9859
9860         local init_grants=$(import_param $osc_tgt initial_grant)
9861         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9862         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9863         local gbs=$(import_param $osc_tgt grant_block_size)
9864         local chunk=$(grant_chunk $osc_tgt)
9865
9866         # write random number of bytes from max_brw_size / 4 to max_brw_size
9867         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9868         # align for direct io
9869         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9870         # round to grant consumption unit
9871         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9872
9873         local grants=$((wb_round_up + extent_tax))
9874
9875         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9876         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9877                 error "error writing to $DIR/$tfile"
9878
9879         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9880                 "direct io with grant allocation"
9881
9882         rm -f $DIR/$tfile || error "rm failed"
9883
9884         # Remount client to reset grant
9885         remount_client $MOUNT || error "failed to remount client"
9886         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9887
9888         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9889
9890         # Testing that buffered IO consumes grant on the client
9891
9892         # Delay the RPC on the server so it's guaranteed to not complete even
9893         # if the RPC is sent from the client
9894         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9895         $LCTL set_param fail_loc=0x50a fail_val=3
9896         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9897                 error "error writing to $DIR/$tfile with buffered IO"
9898
9899         check_grants $osc_tgt $((init_grants - grants)) \
9900                 "buffered io, not write rpc"
9901
9902         # Clear the fail loc and do a sync on the client
9903         $LCTL set_param fail_loc=0 fail_val=0
9904         sync
9905
9906         # RPC is now known to have sent
9907         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9908                 "buffered io, one RPC"
9909 }
9910 run_test 64f "check grant consumption (with grant allocation)"
9911
9912 test_64g() {
9913         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9914                 skip "Need MDS version at least 2.14.56"
9915
9916         local mdts=$(comma_list $(mdts_nodes))
9917
9918         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9919                         tr '\n' ' ')
9920         stack_trap "$LCTL set_param $old"
9921
9922         # generate dirty pages and increase dirty granted on MDT
9923         stack_trap "rm -f $DIR/$tfile-*"
9924         for (( i = 0; i < 10; i++)); do
9925                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9926                         error "can't set stripe"
9927                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9928                         error "can't dd"
9929                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9930                         $LFS getstripe $DIR/$tfile-$i
9931                         error "not DoM file"
9932                 }
9933         done
9934
9935         # flush dirty pages
9936         sync
9937
9938         # wait until grant shrink reset grant dirty on MDTs
9939         for ((i = 0; i < 120; i++)); do
9940                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9941                         awk '{sum=sum+$1} END {print sum}')
9942                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9943                 echo "$grant_dirty grants, $vm_dirty pages"
9944                 (( grant_dirty + vm_dirty == 0 )) && break
9945                 (( i == 3 )) && sync &&
9946                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9947                 sleep 1
9948         done
9949
9950         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9951                 awk '{sum=sum+$1} END {print sum}')
9952         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9953 }
9954 run_test 64g "grant shrink on MDT"
9955
9956 test_64h() {
9957         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9958                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9959
9960         local instance=$($LFS getname -i $DIR)
9961         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9962         local num_exps=$(do_facet ost1 \
9963             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9964         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9965         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9966         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9967
9968         # 10MiB is for file to be written, max_brw_size * 16 *
9969         # num_exps is space reserve so that tgt_grant_shrink() decided
9970         # to not shrink
9971         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9972         (( avail * 1024 < expect )) &&
9973                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9974
9975         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9976         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9977         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9978         $LCTL set_param osc.*OST0000*.grant_shrink=1
9979         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9980
9981         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9982         stack_trap "rm -f $DIR/$tfile"
9983         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9984
9985         # drop cache so that coming read would do rpc
9986         cancel_lru_locks osc
9987
9988         # shrink interval is set to 10, pause for 7 seconds so that
9989         # grant thread did not wake up yet but coming read entered
9990         # shrink mode for rpc (osc_should_shrink_grant())
9991         sleep 7
9992
9993         declare -a cur_grant_bytes
9994         declare -a tot_granted
9995         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9996         tot_granted[0]=$(do_facet ost1 \
9997             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9998
9999         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
10000
10001         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
10002         tot_granted[1]=$(do_facet ost1 \
10003             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
10004
10005         # grant change should be equal on both sides
10006         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
10007                 tot_granted[0] - tot_granted[1])) ||
10008                 error "grant change mismatch, "                                \
10009                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
10010                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
10011 }
10012 run_test 64h "grant shrink on read"
10013
10014 test_64i() {
10015         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
10016                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
10017
10018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10019         remote_ost_nodsh && skip "remote OSTs with nodsh"
10020
10021         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10022         stack_trap "rm -f $DIR/$tfile"
10023
10024         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
10025
10026         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
10027         local instance=$($LFS getname -i $DIR)
10028
10029         local osc_tgt="$FSNAME-OST0000-osc-$instance"
10030         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
10031
10032         # shrink grants and simulate rpc loss
10033         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10034         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10035         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10036
10037         fail ost1
10038
10039         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10040
10041         local testid=$(echo $TESTNAME | tr '_' ' ')
10042
10043         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10044                 grep "GRANT, real grant" &&
10045                 error "client has more grants then it owns" || true
10046 }
10047 run_test 64i "shrink on reconnect"
10048
10049 # bug 1414 - set/get directories' stripe info
10050 test_65a() {
10051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10052
10053         # LU-16904 check if the root is set as PFL layout
10054         local numcomp=$($LFS getstripe --component-count $MOUNT)
10055         [ $numcomp -eq 0 ] || skip "Skip test_65a for PFL layout"
10056
10057         test_mkdir $DIR/$tdir
10058         touch $DIR/$tdir/f1
10059         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10060 }
10061 run_test 65a "directory with no stripe info"
10062
10063 test_65b() {
10064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10065
10066         test_mkdir $DIR/$tdir
10067         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10068
10069         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10070                                                 error "setstripe"
10071         touch $DIR/$tdir/f2
10072         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10073 }
10074 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10075
10076 test_65c() {
10077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10078         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10079
10080         test_mkdir $DIR/$tdir
10081         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10082
10083         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10084                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10085         touch $DIR/$tdir/f3
10086         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10087 }
10088 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10089
10090 test_65d() {
10091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10092
10093         test_mkdir $DIR/$tdir
10094         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10095         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10096
10097         if [[ $STRIPECOUNT -le 0 ]]; then
10098                 sc=1
10099         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10100                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10101                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10102         else
10103                 sc=$(($STRIPECOUNT - 1))
10104         fi
10105         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10106         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10107         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10108                 error "lverify failed"
10109 }
10110 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10111
10112 test_65e() {
10113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10114
10115         # LU-16904 delete layout when root is set as PFL layout
10116         save_layout_restore_at_exit $MOUNT
10117         $LFS setstripe -d $MOUNT || error "setstripe failed"
10118
10119         test_mkdir $DIR/$tdir
10120
10121         $LFS setstripe $DIR/$tdir || error "setstripe"
10122         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10123                                         error "no stripe info failed"
10124         touch $DIR/$tdir/f6
10125         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10126 }
10127 run_test 65e "directory setstripe defaults"
10128
10129 test_65f() {
10130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10131
10132         test_mkdir $DIR/${tdir}f
10133         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10134                 error "setstripe succeeded" || true
10135 }
10136 run_test 65f "dir setstripe permission (should return error) ==="
10137
10138 test_65g() {
10139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10140
10141         # LU-16904 delete layout when root is set as PFL layout
10142         save_layout_restore_at_exit $MOUNT
10143         $LFS setstripe -d $MOUNT || error "setstripe failed"
10144
10145         test_mkdir $DIR/$tdir
10146         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10147
10148         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10149                 error "setstripe -S failed"
10150         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10151         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10152                 error "delete default stripe failed"
10153 }
10154 run_test 65g "directory setstripe -d"
10155
10156 test_65h() {
10157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10158
10159         test_mkdir $DIR/$tdir
10160         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10161
10162         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10163                 error "setstripe -S failed"
10164         test_mkdir $DIR/$tdir/dd1
10165         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10166                 error "stripe info inherit failed"
10167 }
10168 run_test 65h "directory stripe info inherit ===================="
10169
10170 test_65i() {
10171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10172
10173         save_layout_restore_at_exit $MOUNT
10174
10175         # bug6367: set non-default striping on root directory
10176         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10177
10178         # bug12836: getstripe on -1 default directory striping
10179         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10180
10181         # bug12836: getstripe -v on -1 default directory striping
10182         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10183
10184         # bug12836: new find on -1 default directory striping
10185         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10186 }
10187 run_test 65i "various tests to set root directory striping"
10188
10189 test_65j() { # bug6367
10190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10191
10192         sync; sleep 1
10193
10194         # if we aren't already remounting for each test, do so for this test
10195         if [ "$I_MOUNTED" = "yes" ]; then
10196                 cleanup || error "failed to unmount"
10197                 setup
10198         fi
10199
10200         save_layout_restore_at_exit $MOUNT
10201
10202         $LFS setstripe -d $MOUNT || error "setstripe failed"
10203 }
10204 run_test 65j "set default striping on root directory (bug 6367)="
10205
10206 cleanup_65k() {
10207         rm -rf $DIR/$tdir
10208         wait_delete_completed
10209         do_facet $SINGLEMDS "lctl set_param -n \
10210                 osp.$ost*MDT0000.max_create_count=$max_count"
10211         do_facet $SINGLEMDS "lctl set_param -n \
10212                 osp.$ost*MDT0000.create_count=$count"
10213         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10214         echo $INACTIVE_OSC "is Activate"
10215
10216         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10217 }
10218
10219 test_65k() { # bug11679
10220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10221         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10222         remote_mds_nodsh && skip "remote MDS with nodsh"
10223
10224         local disable_precreate=true
10225         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10226                 disable_precreate=false
10227
10228         echo "Check OST status: "
10229         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10230                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10231
10232         for OSC in $MDS_OSCS; do
10233                 echo $OSC "is active"
10234                 do_facet $SINGLEMDS lctl --device %$OSC activate
10235         done
10236
10237         for INACTIVE_OSC in $MDS_OSCS; do
10238                 local ost=$(osc_to_ost $INACTIVE_OSC)
10239                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10240                                lov.*md*.target_obd |
10241                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10242
10243                 mkdir -p $DIR/$tdir
10244                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10245                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10246
10247                 echo "Deactivate: " $INACTIVE_OSC
10248                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10249
10250                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10251                               osp.$ost*MDT0000.create_count")
10252                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10253                                   osp.$ost*MDT0000.max_create_count")
10254                 $disable_precreate &&
10255                         do_facet $SINGLEMDS "lctl set_param -n \
10256                                 osp.$ost*MDT0000.max_create_count=0"
10257
10258                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10259                         [ -f $DIR/$tdir/$idx ] && continue
10260                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10261                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10262                                 { cleanup_65k;
10263                                   error "setstripe $idx should succeed"; }
10264                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10265                 done
10266                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10267                 rmdir $DIR/$tdir
10268
10269                 do_facet $SINGLEMDS "lctl set_param -n \
10270                         osp.$ost*MDT0000.max_create_count=$max_count"
10271                 do_facet $SINGLEMDS "lctl set_param -n \
10272                         osp.$ost*MDT0000.create_count=$count"
10273                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10274                 echo $INACTIVE_OSC "is Activate"
10275
10276                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10277         done
10278 }
10279 run_test 65k "validate manual striping works properly with deactivated OSCs"
10280
10281 test_65l() { # bug 12836
10282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10283
10284         test_mkdir -p $DIR/$tdir/test_dir
10285         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10286         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10287 }
10288 run_test 65l "lfs find on -1 stripe dir ========================"
10289
10290 test_65m() {
10291         local layout=$(save_layout $MOUNT)
10292         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10293                 restore_layout $MOUNT $layout
10294                 error "setstripe should fail by non-root users"
10295         }
10296         true
10297 }
10298 run_test 65m "normal user can't set filesystem default stripe"
10299
10300 test_65n() {
10301         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10302         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10303                 skip "Need MDS version at least 2.12.50"
10304         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10305
10306         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10307         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10308         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10309
10310         save_layout_restore_at_exit $MOUNT
10311
10312         # new subdirectory under root directory should not inherit
10313         # the default layout from root
10314         # LU-16904 check if the root is set as PFL layout
10315         local numcomp=$($LFS getstripe --component-count $MOUNT)
10316
10317         if [[ $numcomp -eq 0 ]]; then
10318                 local dir1=$MOUNT/$tdir-1
10319                 mkdir $dir1 || error "mkdir $dir1 failed"
10320                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10321                         error "$dir1 shouldn't have LOV EA"
10322         fi
10323
10324         # delete the default layout on root directory
10325         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10326
10327         local dir2=$MOUNT/$tdir-2
10328         mkdir $dir2 || error "mkdir $dir2 failed"
10329         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10330                 error "$dir2 shouldn't have LOV EA"
10331
10332         # set a new striping pattern on root directory
10333         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10334         local new_def_stripe_size=$((def_stripe_size * 2))
10335         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10336                 error "set stripe size on $MOUNT failed"
10337
10338         # new file created in $dir2 should inherit the new stripe size from
10339         # the filesystem default
10340         local file2=$dir2/$tfile-2
10341         touch $file2 || error "touch $file2 failed"
10342
10343         local file2_stripe_size=$($LFS getstripe -S $file2)
10344         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10345         {
10346                 echo "file2_stripe_size: '$file2_stripe_size'"
10347                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10348                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10349         }
10350
10351         local dir3=$MOUNT/$tdir-3
10352         mkdir $dir3 || error "mkdir $dir3 failed"
10353         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10354         # the root layout, which is the actual default layout that will be used
10355         # when new files are created in $dir3.
10356         local dir3_layout=$(get_layout_param $dir3)
10357         local root_dir_layout=$(get_layout_param $MOUNT)
10358         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10359         {
10360                 echo "dir3_layout: '$dir3_layout'"
10361                 echo "root_dir_layout: '$root_dir_layout'"
10362                 error "$dir3 should show the default layout from $MOUNT"
10363         }
10364
10365         # set OST pool on root directory
10366         local pool=$TESTNAME
10367         pool_add $pool || error "add $pool failed"
10368         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10369                 error "add targets to $pool failed"
10370
10371         $LFS setstripe -p $pool $MOUNT ||
10372                 error "set OST pool on $MOUNT failed"
10373
10374         # new file created in $dir3 should inherit the pool from
10375         # the filesystem default
10376         local file3=$dir3/$tfile-3
10377         touch $file3 || error "touch $file3 failed"
10378
10379         local file3_pool=$($LFS getstripe -p $file3)
10380         [[ "$file3_pool" = "$pool" ]] ||
10381                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10382
10383         local dir4=$MOUNT/$tdir-4
10384         mkdir $dir4 || error "mkdir $dir4 failed"
10385         local dir4_layout=$(get_layout_param $dir4)
10386         root_dir_layout=$(get_layout_param $MOUNT)
10387         echo "$LFS getstripe -d $dir4"
10388         $LFS getstripe -d $dir4
10389         echo "$LFS getstripe -d $MOUNT"
10390         $LFS getstripe -d $MOUNT
10391         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10392         {
10393                 echo "dir4_layout: '$dir4_layout'"
10394                 echo "root_dir_layout: '$root_dir_layout'"
10395                 error "$dir4 should show the default layout from $MOUNT"
10396         }
10397
10398         # new file created in $dir4 should inherit the pool from
10399         # the filesystem default
10400         local file4=$dir4/$tfile-4
10401         touch $file4 || error "touch $file4 failed"
10402
10403         local file4_pool=$($LFS getstripe -p $file4)
10404         [[ "$file4_pool" = "$pool" ]] ||
10405                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10406
10407         # new subdirectory under non-root directory should inherit
10408         # the default layout from its parent directory
10409         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10410                 error "set directory layout on $dir4 failed"
10411
10412         local dir5=$dir4/$tdir-5
10413         mkdir $dir5 || error "mkdir $dir5 failed"
10414
10415         dir4_layout=$(get_layout_param $dir4)
10416         local dir5_layout=$(get_layout_param $dir5)
10417         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10418         {
10419                 echo "dir4_layout: '$dir4_layout'"
10420                 echo "dir5_layout: '$dir5_layout'"
10421                 error "$dir5 should inherit the default layout from $dir4"
10422         }
10423
10424         # though subdir under ROOT doesn't inherit default layout, but
10425         # its sub dir/file should be created with default layout.
10426         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10427         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10428                 skip "Need MDS version at least 2.12.59"
10429
10430         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10431         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10432         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10433
10434         if [ $default_lmv_hash == "none" ]; then
10435                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10436         else
10437                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10438                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10439         fi
10440
10441         $LFS setdirstripe -D -c 2 $MOUNT ||
10442                 error "setdirstripe -D -c 2 failed"
10443         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10444         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10445         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10446
10447         # $dir4 layout includes pool
10448         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10449         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10450                 error "pool lost on setstripe"
10451         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10452         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10453                 error "pool lost on compound layout setstripe"
10454 }
10455 run_test 65n "don't inherit default layout from root for new subdirectories"
10456
10457 test_65o() {
10458         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10459                 skip "need MDS version at least 2.14.57"
10460
10461         # set OST pool on root directory
10462         local pool=$TESTNAME
10463
10464         pool_add $pool || error "add $pool failed"
10465         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10466                 error "add targets to $pool failed"
10467
10468         local dir1=$MOUNT/$tdir
10469
10470         mkdir $dir1 || error "mkdir $dir1 failed"
10471
10472         # set a new striping pattern on root directory
10473         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10474
10475         $LFS setstripe -p $pool $dir1 ||
10476                 error "set directory layout on $dir1 failed"
10477
10478         # $dir1 layout includes pool
10479         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10480         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10481                 error "pool lost on setstripe"
10482         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10483         $LFS getstripe $dir1
10484         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10485                 error "pool lost on compound layout setstripe"
10486
10487         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10488                 error "setdirstripe failed on sub-dir with inherited pool"
10489         $LFS getstripe $dir1/dir2
10490         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10491                 error "pool lost on compound layout setdirstripe"
10492
10493         $LFS setstripe -E -1 -c 1 $dir1
10494         $LFS getstripe -d $dir1
10495         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10496                 error "pool lost on setstripe"
10497 }
10498 run_test 65o "pool inheritance for mdt component"
10499
10500 test_65p () { # LU-16152
10501         local src_dir=$DIR/$tdir/src_dir
10502         local dst_dir=$DIR/$tdir/dst_dir
10503         local yaml_file=$DIR/$tdir/layout.yaml
10504         local border
10505
10506         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10507                 skip "Need at least version 2.15.51"
10508
10509         test_mkdir -p $src_dir
10510         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10511                 error "failed to setstripe"
10512         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10513                 error "failed to getstripe"
10514
10515         test_mkdir -p $dst_dir
10516         $LFS setstripe --yaml $yaml_file $dst_dir ||
10517                 error "failed to setstripe with yaml file"
10518         border=$($LFS getstripe -d $dst_dir |
10519                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10520                 error "failed to getstripe"
10521
10522         # 2048M is 0x80000000, or 2147483648
10523         (( $border == 2147483648 )) ||
10524                 error "failed to handle huge number in yaml layout"
10525 }
10526 run_test 65p "setstripe with yaml file and huge number"
10527
10528 test_65q () { # LU-16194
10529         local src_dir=$DIR/$tdir/src_dir
10530
10531         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10532         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10533                 skip "Need at least version 2.15.51"
10534
10535         test_mkdir -p $src_dir
10536         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10537         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10538                 error "should fail if extent start/end >=8E"
10539
10540         # EOF should work as before
10541         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10542                 error "failed to setstripe normally"
10543 }
10544 run_test 65q "setstripe with >=8E offset should fail"
10545
10546 # bug 2543 - update blocks count on client
10547 test_66() {
10548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10549
10550         local COUNT=${COUNT:-8}
10551         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10552         sync; sync_all_data; sync; sync_all_data
10553         cancel_lru_locks osc
10554         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10555         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10556 }
10557 run_test 66 "update inode blocks count on client ==============="
10558
10559 meminfo() {
10560         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10561 }
10562
10563 swap_used() {
10564         swapon -s | awk '($1 == "'$1'") { print $4 }'
10565 }
10566
10567 # bug5265, obdfilter oa2dentry return -ENOENT
10568 # #define OBD_FAIL_SRV_ENOENT 0x217
10569 test_69() {
10570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10571         remote_ost_nodsh && skip "remote OST with nodsh"
10572
10573         f="$DIR/$tfile"
10574         $LFS setstripe -c 1 -i 0 $f
10575         stack_trap "rm -f $f ${f}.2"
10576
10577         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10578
10579         do_facet ost1 lctl set_param fail_loc=0x217
10580         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10581         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10582
10583         do_facet ost1 lctl set_param fail_loc=0
10584         $DIRECTIO write $f 0 2 || error "write error"
10585
10586         cancel_lru_locks osc
10587         $DIRECTIO read $f 0 1 || error "read error"
10588
10589         do_facet ost1 lctl set_param fail_loc=0x217
10590         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10591
10592         do_facet ost1 lctl set_param fail_loc=0
10593 }
10594 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10595
10596 test_70a() {
10597         # Perform a really simple test of health write and health check
10598         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10599                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10600
10601         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10602
10603         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10604
10605         # Test with health write off
10606         do_facet ost1 $LCTL set_param enable_health_write off ||
10607                 error "can't set enable_health_write off"
10608         do_facet ost1 $LCTL get_param enable_health_write ||
10609                 error "can't get enable_health_write"
10610
10611         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10612                 error "not healthy (1)"
10613
10614         # Test with health write on
10615         do_facet ost1 $LCTL set_param enable_health_write on ||
10616                 error "can't set enable_health_write on"
10617         do_facet ost1 $LCTL get_param enable_health_write ||
10618                 error "can't get enable_health_write"
10619
10620         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10621                 error "not healthy (2)"
10622 }
10623 run_test 70a "verify health_check, health_write don't explode (on OST)"
10624
10625 test_71() {
10626         test_mkdir $DIR/$tdir
10627         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10628         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10629 }
10630 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10631
10632 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10634         [ "$RUNAS_ID" = "$UID" ] &&
10635                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10636         # Check that testing environment is properly set up. Skip if not
10637         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10638                 skip_env "User $RUNAS_ID does not exist - skipping"
10639
10640         touch $DIR/$tfile
10641         chmod 777 $DIR/$tfile
10642         chmod ug+s $DIR/$tfile
10643         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10644                 error "$RUNAS dd $DIR/$tfile failed"
10645         # See if we are still setuid/sgid
10646         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10647                 error "S/gid is not dropped on write"
10648         # Now test that MDS is updated too
10649         cancel_lru_locks mdc
10650         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10651                 error "S/gid is not dropped on MDS"
10652         rm -f $DIR/$tfile
10653 }
10654 run_test 72a "Test that remove suid works properly (bug5695) ===="
10655
10656 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10657         local perm
10658
10659         [ "$RUNAS_ID" = "$UID" ] &&
10660                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10661         [ "$RUNAS_ID" -eq 0 ] &&
10662                 skip_env "RUNAS_ID = 0 -- skipping"
10663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10664         # Check that testing environment is properly set up. Skip if not
10665         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10666                 skip_env "User $RUNAS_ID does not exist - skipping"
10667
10668         touch $DIR/${tfile}-f{g,u}
10669         test_mkdir $DIR/${tfile}-dg
10670         test_mkdir $DIR/${tfile}-du
10671         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10672         chmod g+s $DIR/${tfile}-{f,d}g
10673         chmod u+s $DIR/${tfile}-{f,d}u
10674         for perm in 777 2777 4777; do
10675                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10676                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10677                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10678                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10679         done
10680         true
10681 }
10682 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10683
10684 # bug 3462 - multiple simultaneous MDC requests
10685 test_73() {
10686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10687
10688         test_mkdir $DIR/d73-1
10689         test_mkdir $DIR/d73-2
10690         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10691         pid1=$!
10692
10693         lctl set_param fail_loc=0x80000129
10694         $MULTIOP $DIR/d73-1/f73-2 Oc &
10695         sleep 1
10696         lctl set_param fail_loc=0
10697
10698         $MULTIOP $DIR/d73-2/f73-3 Oc &
10699         pid3=$!
10700
10701         kill -USR1 $pid1
10702         wait $pid1 || return 1
10703
10704         sleep 25
10705
10706         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10707         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10708         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10709
10710         rm -rf $DIR/d73-*
10711 }
10712 run_test 73 "multiple MDC requests (should not deadlock)"
10713
10714 test_74a() { # bug 6149, 6184
10715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10716
10717         touch $DIR/f74a
10718         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10719         #
10720         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10721         # will spin in a tight reconnection loop
10722         $LCTL set_param fail_loc=0x8000030e
10723         # get any lock that won't be difficult - lookup works.
10724         ls $DIR/f74a
10725         $LCTL set_param fail_loc=0
10726         rm -f $DIR/f74a
10727         true
10728 }
10729 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10730
10731 test_74b() { # bug 13310
10732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10733
10734         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10735         #
10736         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10737         # will spin in a tight reconnection loop
10738         $LCTL set_param fail_loc=0x8000030e
10739         # get a "difficult" lock
10740         touch $DIR/f74b
10741         $LCTL set_param fail_loc=0
10742         rm -f $DIR/f74b
10743         true
10744 }
10745 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10746
10747 test_74c() {
10748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10749
10750         #define OBD_FAIL_LDLM_NEW_LOCK
10751         $LCTL set_param fail_loc=0x319
10752         touch $DIR/$tfile && error "touch successful"
10753         $LCTL set_param fail_loc=0
10754         true
10755 }
10756 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10757
10758 slab_lic=/sys/kernel/slab/lustre_inode_cache
10759 num_objects() {
10760         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10761         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10762                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10763 }
10764
10765 test_76a() { # Now for b=20433, added originally in b=1443
10766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10767
10768         cancel_lru_locks osc
10769         # there may be some slab objects cached per core
10770         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10771         local before=$(num_objects)
10772         local count=$((512 * cpus))
10773         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10774         local margin=$((count / 10))
10775         if [[ -f $slab_lic/aliases ]]; then
10776                 local aliases=$(cat $slab_lic/aliases)
10777                 (( aliases > 0 )) && margin=$((margin * aliases))
10778         fi
10779
10780         echo "before slab objects: $before"
10781         for i in $(seq $count); do
10782                 touch $DIR/$tfile
10783                 rm -f $DIR/$tfile
10784         done
10785         cancel_lru_locks osc
10786         local after=$(num_objects)
10787         echo "created: $count, after slab objects: $after"
10788         # shared slab counts are not very accurate, allow significant margin
10789         # the main goal is that the cache growth is not permanently > $count
10790         while (( after > before + margin )); do
10791                 sleep 1
10792                 after=$(num_objects)
10793                 wait=$((wait + 1))
10794                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10795                 if (( wait > 60 )); then
10796                         error "inode slab grew from $before+$margin to $after"
10797                 fi
10798         done
10799 }
10800 run_test 76a "confirm clients recycle inodes properly ===="
10801
10802 test_76b() {
10803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10804         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10805
10806         local count=512
10807         local before=$(num_objects)
10808
10809         for i in $(seq $count); do
10810                 mkdir $DIR/$tdir
10811                 rmdir $DIR/$tdir
10812         done
10813
10814         local after=$(num_objects)
10815         local wait=0
10816
10817         while (( after > before )); do
10818                 sleep 1
10819                 after=$(num_objects)
10820                 wait=$((wait + 1))
10821                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10822                 if (( wait > 60 )); then
10823                         error "inode slab grew from $before to $after"
10824                 fi
10825         done
10826
10827         echo "slab objects before: $before, after: $after"
10828 }
10829 run_test 76b "confirm clients recycle directory inodes properly ===="
10830
10831 export ORIG_CSUM=""
10832 set_checksums()
10833 {
10834         # Note: in sptlrpc modes which enable its own bulk checksum, the
10835         # original crc32_le bulk checksum will be automatically disabled,
10836         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10837         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10838         # In this case set_checksums() will not be no-op, because sptlrpc
10839         # bulk checksum will be enabled all through the test.
10840
10841         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10842         lctl set_param -n osc.*.checksums $1
10843         return 0
10844 }
10845
10846 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10847                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10848 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10849                              tr -d [] | head -n1)}
10850 set_checksum_type()
10851 {
10852         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10853         rc=$?
10854         log "set checksum type to $1, rc = $rc"
10855         return $rc
10856 }
10857
10858 get_osc_checksum_type()
10859 {
10860         # arugment 1: OST name, like OST0000
10861         ost=$1
10862         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10863                         sed 's/.*\[\(.*\)\].*/\1/g')
10864         rc=$?
10865         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10866         echo $checksum_type
10867 }
10868
10869 F77_TMP=$TMP/f77-temp
10870 F77SZ=8
10871 setup_f77() {
10872         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10873                 error "error writing to $F77_TMP"
10874 }
10875
10876 test_77a() { # bug 10889
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878         $GSS && skip_env "could not run with gss"
10879
10880         [ ! -f $F77_TMP ] && setup_f77
10881         set_checksums 1
10882         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10883         set_checksums 0
10884         rm -f $DIR/$tfile
10885 }
10886 run_test 77a "normal checksum read/write operation"
10887
10888 test_77b() { # bug 10889
10889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10890         $GSS && skip_env "could not run with gss"
10891
10892         [ ! -f $F77_TMP ] && setup_f77
10893         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10894         $LCTL set_param fail_loc=0x80000409
10895         set_checksums 1
10896
10897         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10898                 error "dd error: $?"
10899         $LCTL set_param fail_loc=0
10900
10901         for algo in $CKSUM_TYPES; do
10902                 cancel_lru_locks osc
10903                 set_checksum_type $algo
10904                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10905                 $LCTL set_param fail_loc=0x80000408
10906                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10907                 $LCTL set_param fail_loc=0
10908         done
10909         set_checksums 0
10910         set_checksum_type $ORIG_CSUM_TYPE
10911         rm -f $DIR/$tfile
10912 }
10913 run_test 77b "checksum error on client write, read"
10914
10915 cleanup_77c() {
10916         trap 0
10917         set_checksums 0
10918         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10919         $check_ost &&
10920                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10921         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10922         $check_ost && [ -n "$ost_file_prefix" ] &&
10923                 do_facet ost1 rm -f ${ost_file_prefix}\*
10924 }
10925
10926 test_77c() {
10927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10928         $GSS && skip_env "could not run with gss"
10929         remote_ost_nodsh && skip "remote OST with nodsh"
10930
10931         local bad1
10932         local osc_file_prefix
10933         local osc_file
10934         local check_ost=false
10935         local ost_file_prefix
10936         local ost_file
10937         local orig_cksum
10938         local dump_cksum
10939         local fid
10940
10941         # ensure corruption will occur on first OSS/OST
10942         $LFS setstripe -i 0 $DIR/$tfile
10943
10944         [ ! -f $F77_TMP ] && setup_f77
10945         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10946                 error "dd write error: $?"
10947         fid=$($LFS path2fid $DIR/$tfile)
10948
10949         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10950         then
10951                 check_ost=true
10952                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10953                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10954         else
10955                 echo "OSS do not support bulk pages dump upon error"
10956         fi
10957
10958         osc_file_prefix=$($LCTL get_param -n debug_path)
10959         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10960
10961         trap cleanup_77c EXIT
10962
10963         set_checksums 1
10964         # enable bulk pages dump upon error on Client
10965         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10966         # enable bulk pages dump upon error on OSS
10967         $check_ost &&
10968                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10969
10970         # flush Client cache to allow next read to reach OSS
10971         cancel_lru_locks osc
10972
10973         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10974         $LCTL set_param fail_loc=0x80000408
10975         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10976         $LCTL set_param fail_loc=0
10977
10978         rm -f $DIR/$tfile
10979
10980         # check cksum dump on Client
10981         osc_file=$(ls ${osc_file_prefix}*)
10982         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10983         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10984         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10985         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10986         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10987                      cksum)
10988         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10989         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10990                 error "dump content does not match on Client"
10991
10992         $check_ost || skip "No need to check cksum dump on OSS"
10993
10994         # check cksum dump on OSS
10995         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10996         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10997         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10998         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10999         [[ "$orig_cksum" == "$dump_cksum" ]] ||
11000                 error "dump content does not match on OSS"
11001
11002         cleanup_77c
11003 }
11004 run_test 77c "checksum error on client read with debug"
11005
11006 test_77d() { # bug 10889
11007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11008         $GSS && skip_env "could not run with gss"
11009
11010         stack_trap "rm -f $DIR/$tfile"
11011         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11012         $LCTL set_param fail_loc=0x80000409
11013         set_checksums 1
11014         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11015                 error "direct write: rc=$?"
11016         $LCTL set_param fail_loc=0
11017         set_checksums 0
11018
11019         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
11020         $LCTL set_param fail_loc=0x80000408
11021         set_checksums 1
11022         cancel_lru_locks osc
11023         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11024                 error "direct read: rc=$?"
11025         $LCTL set_param fail_loc=0
11026         set_checksums 0
11027 }
11028 run_test 77d "checksum error on OST direct write, read"
11029
11030 test_77f() { # bug 10889
11031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11032         $GSS && skip_env "could not run with gss"
11033
11034         set_checksums 1
11035         stack_trap "rm -f $DIR/$tfile"
11036         for algo in $CKSUM_TYPES; do
11037                 cancel_lru_locks osc
11038                 set_checksum_type $algo
11039                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11040                 $LCTL set_param fail_loc=0x409
11041                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11042                         error "direct write succeeded"
11043                 $LCTL set_param fail_loc=0
11044         done
11045         set_checksum_type $ORIG_CSUM_TYPE
11046         set_checksums 0
11047 }
11048 run_test 77f "repeat checksum error on write (expect error)"
11049
11050 test_77g() { # bug 10889
11051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11052         $GSS && skip_env "could not run with gss"
11053         remote_ost_nodsh && skip "remote OST with nodsh"
11054
11055         [ ! -f $F77_TMP ] && setup_f77
11056
11057         local file=$DIR/$tfile
11058         stack_trap "rm -f $file" EXIT
11059
11060         $LFS setstripe -c 1 -i 0 $file
11061         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11062         do_facet ost1 lctl set_param fail_loc=0x8000021a
11063         set_checksums 1
11064         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11065                 error "write error: rc=$?"
11066         do_facet ost1 lctl set_param fail_loc=0
11067         set_checksums 0
11068
11069         cancel_lru_locks osc
11070         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11071         do_facet ost1 lctl set_param fail_loc=0x8000021b
11072         set_checksums 1
11073         cmp $F77_TMP $file || error "file compare failed"
11074         do_facet ost1 lctl set_param fail_loc=0
11075         set_checksums 0
11076 }
11077 run_test 77g "checksum error on OST write, read"
11078
11079 test_77k() { # LU-10906
11080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11081         $GSS && skip_env "could not run with gss"
11082
11083         local cksum_param="osc.$FSNAME*.checksums"
11084         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11085         local checksum
11086         local i
11087
11088         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11089         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11090         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11091
11092         for i in 0 1; do
11093                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11094                         error "failed to set checksum=$i on MGS"
11095                 wait_update $HOSTNAME "$get_checksum" $i
11096                 #remount
11097                 echo "remount client, checksum should be $i"
11098                 remount_client $MOUNT || error "failed to remount client"
11099                 checksum=$(eval $get_checksum)
11100                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11101         done
11102         # remove persistent param to avoid races with checksum mountopt below
11103         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11104                 error "failed to delete checksum on MGS"
11105
11106         for opt in "checksum" "nochecksum"; do
11107                 #remount with mount option
11108                 echo "remount client with option $opt, checksum should be $i"
11109                 umount_client $MOUNT || error "failed to umount client"
11110                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11111                         error "failed to mount client with option '$opt'"
11112                 checksum=$(eval $get_checksum)
11113                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11114                 i=$((i - 1))
11115         done
11116
11117         remount_client $MOUNT || error "failed to remount client"
11118 }
11119 run_test 77k "enable/disable checksum correctly"
11120
11121 test_77l() {
11122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11123         $GSS && skip_env "could not run with gss"
11124
11125         set_checksums 1
11126         stack_trap "set_checksums $ORIG_CSUM" EXIT
11127         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11128         local old
11129
11130         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11131         $LCTL set_param osc.*.idle_timeout=10
11132         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11133
11134         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11135
11136         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11137         for algo in $CKSUM_TYPES; do
11138                 set_checksum_type $algo || error "fail to set checksum type $algo"
11139                 osc_algo=$(get_osc_checksum_type OST0000)
11140                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11141
11142                 # no locks, no reqs to let the connection idle
11143                 cancel_lru_locks osc
11144                 lru_resize_disable osc
11145                 wait_osc_import_state client ost1 IDLE
11146
11147                 # ensure ost1 is connected
11148                 stat $DIR/$tfile >/dev/null || error "can't stat"
11149                 wait_osc_import_state client ost1 FULL
11150
11151                 osc_algo=$(get_osc_checksum_type OST0000)
11152                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11153         done
11154         return 0
11155 }
11156 run_test 77l "preferred checksum type is remembered after reconnected"
11157
11158 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11159 rm -f $F77_TMP
11160 unset F77_TMP
11161
11162 test_77m() {
11163         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11164                 skip "Need at least version 2.14.52"
11165         local param=checksum_speed
11166
11167         $LCTL get_param $param || error "reading $param failed"
11168
11169         csum_speeds=$($LCTL get_param -n $param)
11170
11171         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11172                 error "known checksum types are missing"
11173 }
11174 run_test 77m "Verify checksum_speed is correctly read"
11175
11176 check_filefrag_77n() {
11177         local nr_ext=0
11178         local starts=()
11179         local ends=()
11180
11181         while read extidx a b start end rest; do
11182                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11183                         nr_ext=$(( $nr_ext + 1 ))
11184                         starts+=( ${start%..} )
11185                         ends+=( ${end%:} )
11186                 fi
11187         done < <( filefrag -sv $1 )
11188
11189         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11190         return 1
11191 }
11192
11193 test_77n() {
11194         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11195
11196         touch $DIR/$tfile
11197         $TRUNCATE $DIR/$tfile 0
11198         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11199         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11200         check_filefrag_77n $DIR/$tfile ||
11201                 skip "$tfile blocks not contiguous around hole"
11202
11203         set_checksums 1
11204         stack_trap "set_checksums $ORIG_CSUM" EXIT
11205         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11206         stack_trap "rm -f $DIR/$tfile"
11207
11208         for algo in $CKSUM_TYPES; do
11209                 if [[ "$algo" =~ ^t10 ]]; then
11210                         set_checksum_type $algo ||
11211                                 error "fail to set checksum type $algo"
11212                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11213                                 error "fail to read $tfile with $algo"
11214                 fi
11215         done
11216         rm -f $DIR/$tfile
11217         return 0
11218 }
11219 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11220
11221 test_77o() {
11222         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11223                 skip "Need MDS version at least 2.14.55"
11224         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11225                 skip "Need OST version at least 2.14.55"
11226         local ofd=obdfilter
11227         local mdt=mdt
11228
11229         # print OST checksum_type
11230         echo "$ofd.$FSNAME-*.checksum_type:"
11231         do_nodes $(comma_list $(osts_nodes)) \
11232                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11233
11234         # print MDT checksum_type
11235         echo "$mdt.$FSNAME-*.checksum_type:"
11236         do_nodes $(comma_list $(mdts_nodes)) \
11237                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11238
11239         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11240                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11241
11242         (( $o_count == $OSTCOUNT )) ||
11243                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11244
11245         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11246                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11247
11248         (( $m_count == $MDSCOUNT )) ||
11249                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11250 }
11251 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11252
11253 cleanup_test_78() {
11254         trap 0
11255         rm -f $DIR/$tfile
11256 }
11257
11258 test_78() { # bug 10901
11259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11260         remote_ost || skip_env "local OST"
11261
11262         NSEQ=5
11263         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11264         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11265         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11266         echo "MemTotal: $MEMTOTAL"
11267
11268         # reserve 256MB of memory for the kernel and other running processes,
11269         # and then take 1/2 of the remaining memory for the read/write buffers.
11270         if [ $MEMTOTAL -gt 512 ] ;then
11271                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11272         else
11273                 # for those poor memory-starved high-end clusters...
11274                 MEMTOTAL=$((MEMTOTAL / 2))
11275         fi
11276         echo "Mem to use for directio: $MEMTOTAL"
11277
11278         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11279         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11280         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11281         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11282                 head -n1)
11283         echo "Smallest OST: $SMALLESTOST"
11284         [[ $SMALLESTOST -lt 10240 ]] &&
11285                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11286
11287         trap cleanup_test_78 EXIT
11288
11289         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11290                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11291
11292         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11293         echo "File size: $F78SIZE"
11294         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11295         for i in $(seq 1 $NSEQ); do
11296                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11297                 echo directIO rdwr round $i of $NSEQ
11298                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11299         done
11300
11301         cleanup_test_78
11302 }
11303 run_test 78 "handle large O_DIRECT writes correctly ============"
11304
11305 test_79() { # bug 12743
11306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11307
11308         wait_delete_completed
11309
11310         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11311         BKFREE=$(calc_osc_kbytes kbytesfree)
11312         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11313
11314         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11315         DFTOTAL=`echo $STRING | cut -d, -f1`
11316         DFUSED=`echo $STRING  | cut -d, -f2`
11317         DFAVAIL=`echo $STRING | cut -d, -f3`
11318         DFFREE=$(($DFTOTAL - $DFUSED))
11319
11320         ALLOWANCE=$((64 * $OSTCOUNT))
11321
11322         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11323            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11324                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11325         fi
11326         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11327            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11328                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11329         fi
11330         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11331            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11332                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11333         fi
11334 }
11335 run_test 79 "df report consistency check ======================="
11336
11337 test_80() { # bug 10718
11338         remote_ost_nodsh && skip "remote OST with nodsh"
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340
11341         # relax strong synchronous semantics for slow backends like ZFS
11342         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11343                 local soc="obdfilter.*.sync_lock_cancel"
11344                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11345
11346                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11347                 if [ -z "$save" ]; then
11348                         soc="obdfilter.*.sync_on_lock_cancel"
11349                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11350                 fi
11351
11352                 if [ "$save" != "never" ]; then
11353                         local hosts=$(comma_list $(osts_nodes))
11354
11355                         do_nodes $hosts $LCTL set_param $soc=never
11356                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11357                 fi
11358         fi
11359
11360         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11361         sync; sleep 1; sync
11362         local before=$(date +%s)
11363         cancel_lru_locks osc
11364         local after=$(date +%s)
11365         local diff=$((after - before))
11366         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11367
11368         rm -f $DIR/$tfile
11369 }
11370 run_test 80 "Page eviction is equally fast at high offsets too"
11371
11372 test_81a() { # LU-456
11373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11374         remote_ost_nodsh && skip "remote OST with nodsh"
11375
11376         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11377         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11378         do_facet ost1 lctl set_param fail_loc=0x80000228
11379
11380         # write should trigger a retry and success
11381         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11382         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11383         RC=$?
11384         if [ $RC -ne 0 ] ; then
11385                 error "write should success, but failed for $RC"
11386         fi
11387 }
11388 run_test 81a "OST should retry write when get -ENOSPC ==============="
11389
11390 test_81b() { # LU-456
11391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11392         remote_ost_nodsh && skip "remote OST with nodsh"
11393
11394         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11395         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11396         do_facet ost1 lctl set_param fail_loc=0x228
11397
11398         # write should retry several times and return -ENOSPC finally
11399         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11400         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11401         RC=$?
11402         ENOSPC=28
11403         if [ $RC -ne $ENOSPC ] ; then
11404                 error "dd should fail for -ENOSPC, but succeed."
11405         fi
11406 }
11407 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11408
11409 test_99() {
11410         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11411
11412         test_mkdir $DIR/$tdir.cvsroot
11413         chown $RUNAS_ID $DIR/$tdir.cvsroot
11414
11415         cd $TMP
11416         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11417
11418         cd /etc/init.d
11419         # some versions of cvs import exit(1) when asked to import links or
11420         # files they can't read.  ignore those files.
11421         local toignore=$(find . -type l -printf '-I %f\n' -o \
11422                          ! -perm /4 -printf '-I %f\n')
11423         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11424                 $tdir.reposname vtag rtag
11425
11426         cd $DIR
11427         test_mkdir $DIR/$tdir.reposname
11428         chown $RUNAS_ID $DIR/$tdir.reposname
11429         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11430
11431         cd $DIR/$tdir.reposname
11432         $RUNAS touch foo99
11433         $RUNAS cvs add -m 'addmsg' foo99
11434         $RUNAS cvs update
11435         $RUNAS cvs commit -m 'nomsg' foo99
11436         rm -fr $DIR/$tdir.cvsroot
11437 }
11438 run_test 99 "cvs strange file/directory operations"
11439
11440 test_100() {
11441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11442         [[ "$NETTYPE" =~ tcp ]] ||
11443                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11444         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11445         remote_ost_nodsh && skip "remote OST with nodsh"
11446         remote_mds_nodsh && skip "remote MDS with nodsh"
11447         remote_servers || skip "useless for local single node setup"
11448
11449         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11450                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11451
11452                 rc=0
11453                 if (( ${LOCAL/*:/} >= 1024 )); then
11454                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11455                         ss -tna
11456                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11457                 fi
11458         done
11459         (( $rc == 0 )) || error "privileged port not found" )
11460 }
11461 run_test 100 "check local port using privileged port"
11462
11463 function get_named_value()
11464 {
11465     local tag=$1
11466
11467     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11468 }
11469
11470 test_101a() {
11471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11472
11473         local s
11474         local discard
11475         local nreads=10000
11476         local cache_limit=32
11477
11478         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11479         $LCTL set_param -n llite.*.read_ahead_stats=0
11480         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11481                               awk '/^max_cached_mb/ { print $2 }')
11482         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11483         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11484
11485         #
11486         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11487         #
11488         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11489         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11490
11491         discard=0
11492         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11493                    get_named_value 'read.but.discarded'); do
11494                         discard=$(($discard + $s))
11495         done
11496
11497         $LCTL get_param osc.*-osc*.rpc_stats
11498         $LCTL get_param llite.*.read_ahead_stats
11499
11500         # Discard is generally zero, but sometimes a few random reads line up
11501         # and trigger larger readahead, which is wasted & leads to discards.
11502         if [[ $(($discard)) -gt $nreads ]]; then
11503                 error "too many ($discard) discarded pages"
11504         fi
11505         rm -f $DIR/$tfile || true
11506 }
11507 run_test 101a "check read-ahead for random reads"
11508
11509 setup_test101bc() {
11510         test_mkdir $DIR/$tdir
11511         local ssize=$1
11512         local FILE_LENGTH=$2
11513         STRIPE_OFFSET=0
11514
11515         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11516
11517         local list=$(comma_list $(osts_nodes))
11518         set_osd_param $list '' read_cache_enable 0
11519         set_osd_param $list '' writethrough_cache_enable 0
11520
11521         trap cleanup_test101bc EXIT
11522         # prepare the read-ahead file
11523         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11524
11525         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11526                                 count=$FILE_SIZE_MB 2> /dev/null
11527
11528 }
11529
11530 cleanup_test101bc() {
11531         trap 0
11532         rm -rf $DIR/$tdir
11533         rm -f $DIR/$tfile
11534
11535         local list=$(comma_list $(osts_nodes))
11536         set_osd_param $list '' read_cache_enable 1
11537         set_osd_param $list '' writethrough_cache_enable 1
11538 }
11539
11540 ra_check_101() {
11541         local read_size=$1
11542         local stripe_size=$2
11543         local stride_length=$((stripe_size / read_size))
11544         local stride_width=$((stride_length * OSTCOUNT))
11545         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11546                                 (stride_width - stride_length) ))
11547         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11548                   get_named_value 'read.but.discarded' | calc_sum)
11549
11550         if [[ $discard -gt $discard_limit ]]; then
11551                 $LCTL get_param llite.*.read_ahead_stats
11552                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11553         else
11554                 echo "Read-ahead success for size ${read_size}"
11555         fi
11556 }
11557
11558 test_101b() {
11559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11560         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11561
11562         local STRIPE_SIZE=1048576
11563         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11564
11565         if [ $SLOW == "yes" ]; then
11566                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11567         else
11568                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11569         fi
11570
11571         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11572
11573         # prepare the read-ahead file
11574         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11575         cancel_lru_locks osc
11576         for BIDX in 2 4 8 16 32 64 128 256
11577         do
11578                 local BSIZE=$((BIDX*4096))
11579                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11580                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11581                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11582                 $LCTL set_param -n llite.*.read_ahead_stats=0
11583                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11584                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11585                 cancel_lru_locks osc
11586                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11587         done
11588         cleanup_test101bc
11589         true
11590 }
11591 run_test 101b "check stride-io mode read-ahead ================="
11592
11593 test_101c() {
11594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11595
11596         local STRIPE_SIZE=1048576
11597         local FILE_LENGTH=$((STRIPE_SIZE*100))
11598         local nreads=10000
11599         local rsize=65536
11600         local osc_rpc_stats
11601
11602         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11603
11604         cancel_lru_locks osc
11605         $LCTL set_param osc.*.rpc_stats=0
11606         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11607         $LCTL get_param osc.*.rpc_stats
11608         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11609                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11610                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11611                 local size
11612
11613                 if [ $lines -le 20 ]; then
11614                         echo "continue debug"
11615                         continue
11616                 fi
11617                 for size in 1 2 4 8; do
11618                         local rpc=$(echo "$stats" |
11619                                     awk '($1 == "'$size':") {print $2; exit; }')
11620                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11621                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11622                 done
11623                 echo "$osc_rpc_stats check passed!"
11624         done
11625         cleanup_test101bc
11626         true
11627 }
11628 run_test 101c "check stripe_size aligned read-ahead"
11629
11630 test_101d() {
11631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11632
11633         local file=$DIR/$tfile
11634         local sz_MB=${FILESIZE_101d:-80}
11635         local ra_MB=${READAHEAD_MB:-40}
11636
11637         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11638         [ $free_MB -lt $sz_MB ] &&
11639                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11640
11641         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11642         $LFS setstripe -c -1 $file || error "setstripe failed"
11643
11644         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11645         echo Cancel LRU locks on lustre client to flush the client cache
11646         cancel_lru_locks osc
11647
11648         echo Disable read-ahead
11649         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11650         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11651         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11652         $LCTL get_param -n llite.*.max_read_ahead_mb
11653
11654         echo "Reading the test file $file with read-ahead disabled"
11655         local sz_KB=$((sz_MB * 1024 / 4))
11656         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11657         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11658         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11659         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11660                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11661
11662         echo "Cancel LRU locks on lustre client to flush the client cache"
11663         cancel_lru_locks osc
11664         echo Enable read-ahead with ${ra_MB}MB
11665         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11666
11667         echo "Reading the test file $file with read-ahead enabled"
11668         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11669                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11670
11671         echo "read-ahead disabled time read '$raOFF'"
11672         echo "read-ahead enabled time read '$raON'"
11673
11674         rm -f $file
11675         wait_delete_completed
11676
11677         # use awk for this check instead of bash because it handles decimals
11678         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11679                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11680 }
11681 run_test 101d "file read with and without read-ahead enabled"
11682
11683 test_101e() {
11684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11685
11686         local file=$DIR/$tfile
11687         local size_KB=500  #KB
11688         local count=100
11689         local bsize=1024
11690
11691         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11692         local need_KB=$((count * size_KB))
11693         [[ $free_KB -le $need_KB ]] &&
11694                 skip_env "Need free space $need_KB, have $free_KB"
11695
11696         echo "Creating $count ${size_KB}K test files"
11697         for ((i = 0; i < $count; i++)); do
11698                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11699         done
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         for ((i = 0; i < $count; i++)); do
11708                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11709         done
11710
11711         $LCTL get_param llite.*.max_cached_mb
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         for ((i = 0; i < $count; i++)); do
11717                 rm -rf $file.$i 2>/dev/null
11718         done
11719
11720         #10000 means 20% reads are missing in readahead
11721         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11722 }
11723 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11724
11725 test_101f() {
11726         which iozone || skip_env "no iozone installed"
11727
11728         local old_debug=$($LCTL get_param debug)
11729         old_debug=${old_debug#*=}
11730         $LCTL set_param debug="reada mmap"
11731
11732         # create a test file
11733         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11734
11735         echo Cancel LRU locks on lustre client to flush the client cache
11736         cancel_lru_locks osc
11737
11738         echo Reset readahead stats
11739         $LCTL set_param -n llite.*.read_ahead_stats=0
11740
11741         echo mmap read the file with small block size
11742         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11743                 > /dev/null 2>&1
11744
11745         echo checking missing pages
11746         $LCTL get_param llite.*.read_ahead_stats
11747         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11748                         get_named_value 'misses' | calc_sum)
11749
11750         $LCTL set_param debug="$old_debug"
11751         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11752         rm -f $DIR/$tfile
11753 }
11754 run_test 101f "check mmap read performance"
11755
11756 test_101g_brw_size_test() {
11757         local mb=$1
11758         local pages=$((mb * 1048576 / PAGE_SIZE))
11759         local file=$DIR/$tfile
11760
11761         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11762                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11763         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11764                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11765                         return 2
11766         done
11767
11768         stack_trap "rm -f $file" EXIT
11769         $LCTL set_param -n osc.*.rpc_stats=0
11770
11771         # 10 RPCs should be enough for the test
11772         local count=10
11773         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11774                 { error "dd write ${mb} MB blocks failed"; return 3; }
11775         cancel_lru_locks osc
11776         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11777                 { error "dd write ${mb} MB blocks failed"; return 4; }
11778
11779         # calculate number of full-sized read and write RPCs
11780         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11781                 sed -n '/pages per rpc/,/^$/p' |
11782                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11783                 END { print reads,writes }'))
11784         # allow one extra full-sized read RPC for async readahead
11785         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11786                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11787         [[ ${rpcs[1]} == $count ]] ||
11788                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11789 }
11790
11791 test_101g() {
11792         remote_ost_nodsh && skip "remote OST with nodsh"
11793
11794         local rpcs
11795         local osts=$(get_facets OST)
11796         local list=$(comma_list $(osts_nodes))
11797         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11798         local brw_size="obdfilter.*.brw_size"
11799
11800         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11801
11802         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11803
11804         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11805                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11806                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11807            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11808                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11809                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11810
11811                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11812                         suffix="M"
11813
11814                 if [[ $orig_mb -lt 16 ]]; then
11815                         save_lustre_params $osts "$brw_size" > $p
11816                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11817                                 error "set 16MB RPC size failed"
11818
11819                         echo "remount client to enable new RPC size"
11820                         remount_client $MOUNT || error "remount_client failed"
11821                 fi
11822
11823                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11824                 # should be able to set brw_size=12, but no rpc_stats for that
11825                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11826         fi
11827
11828         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11829
11830         if [[ $orig_mb -lt 16 ]]; then
11831                 restore_lustre_params < $p
11832                 remount_client $MOUNT || error "remount_client restore failed"
11833         fi
11834
11835         rm -f $p $DIR/$tfile
11836 }
11837 run_test 101g "Big bulk(4/16 MiB) readahead"
11838
11839 test_101h() {
11840         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11841
11842         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11843                 error "dd 70M file failed"
11844         echo Cancel LRU locks on lustre client to flush the client cache
11845         cancel_lru_locks osc
11846
11847         echo "Reset readahead stats"
11848         $LCTL set_param -n llite.*.read_ahead_stats 0
11849
11850         echo "Read 10M of data but cross 64M bundary"
11851         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11852         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11853                      get_named_value 'misses' | calc_sum)
11854         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11855         rm -f $p $DIR/$tfile
11856 }
11857 run_test 101h "Readahead should cover current read window"
11858
11859 test_101i() {
11860         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11861                 error "dd 10M file failed"
11862
11863         local max_per_file_mb=$($LCTL get_param -n \
11864                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11865         cancel_lru_locks osc
11866         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11867         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11868                 error "set max_read_ahead_per_file_mb to 1 failed"
11869
11870         echo "Reset readahead stats"
11871         $LCTL set_param llite.*.read_ahead_stats=0
11872
11873         dd if=$DIR/$tfile of=/dev/null bs=2M
11874
11875         $LCTL get_param llite.*.read_ahead_stats
11876         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11877                      awk '/misses/ { print $2 }')
11878         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11879         rm -f $DIR/$tfile
11880 }
11881 run_test 101i "allow current readahead to exceed reservation"
11882
11883 test_101j() {
11884         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11885                 error "setstripe $DIR/$tfile failed"
11886         local file_size=$((1048576 * 16))
11887         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11888         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11889
11890         echo Disable read-ahead
11891         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11892
11893         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11894         for blk in $PAGE_SIZE 1048576 $file_size; do
11895                 cancel_lru_locks osc
11896                 echo "Reset readahead stats"
11897                 $LCTL set_param -n llite.*.read_ahead_stats=0
11898                 local count=$(($file_size / $blk))
11899                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11900                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11901                              get_named_value 'failed.to.fast.read' | calc_sum)
11902                 $LCTL get_param -n llite.*.read_ahead_stats
11903                 [ $miss -eq $count ] || error "expected $count got $miss"
11904         done
11905
11906         rm -f $p $DIR/$tfile
11907 }
11908 run_test 101j "A complete read block should be submitted when no RA"
11909
11910 test_readahead_base() {
11911         local file=$DIR/$tfile
11912         local size=$1
11913         local iosz
11914         local ramax
11915         local ranum
11916
11917         $LCTL set_param -n llite.*.read_ahead_stats=0
11918         # The first page is not accounted into readahead
11919         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11920         iosz=$(((size + 1048575) / 1048576 * 1048576))
11921         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11922
11923         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11924         fallocate -l $size $file || error "failed to fallocate $file"
11925         cancel_lru_locks osc
11926         $MULTIOP $file or${iosz}c || error "failed to read $file"
11927         $LCTL get_param -n llite.*.read_ahead_stats
11928         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11929                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11930         (( $ranum <= $ramax )) ||
11931                 error "read-ahead pages is $ranum more than $ramax"
11932         rm -rf $file || error "failed to remove $file"
11933 }
11934
11935 test_101m()
11936 {
11937         local file=$DIR/$tfile
11938         local ramax
11939         local ranum
11940         local size
11941         local iosz
11942
11943         check_set_fallocate_or_skip
11944         stack_trap "rm -f $file" EXIT
11945
11946         test_readahead_base 4096
11947
11948         # file size: 16K = 16384
11949         test_readahead_base 16384
11950         test_readahead_base 16385
11951         test_readahead_base 16383
11952
11953         # file size: 1M + 1 = 1048576 + 1
11954         test_readahead_base 1048577
11955         # file size: 1M + 16K
11956         test_readahead_base $((1048576 + 16384))
11957
11958         # file size: stripe_size * (stripe_count - 1) + 16K
11959         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11960         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11961         # file size: stripe_size * stripe_count + 16K
11962         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11963         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11964         # file size: 2 * stripe_size * stripe_count + 16K
11965         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11966         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11967 }
11968 run_test 101m "read ahead for small file and last stripe of the file"
11969
11970 setup_test102() {
11971         test_mkdir $DIR/$tdir
11972         chown $RUNAS_ID $DIR/$tdir
11973         STRIPE_SIZE=65536
11974         STRIPE_OFFSET=1
11975         STRIPE_COUNT=$OSTCOUNT
11976         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11977
11978         trap cleanup_test102 EXIT
11979         cd $DIR
11980         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11981         cd $DIR/$tdir
11982         for num in 1 2 3 4; do
11983                 for count in $(seq 1 $STRIPE_COUNT); do
11984                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11985                                 local size=`expr $STRIPE_SIZE \* $num`
11986                                 local file=file"$num-$idx-$count"
11987                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11988                         done
11989                 done
11990         done
11991
11992         cd $DIR
11993         $1 tar cf $TMP/f102.tar $tdir --xattrs
11994 }
11995
11996 cleanup_test102() {
11997         trap 0
11998         rm -f $TMP/f102.tar
11999         rm -rf $DIR/d0.sanity/d102
12000 }
12001
12002 test_102a() {
12003         [ "$UID" != 0 ] && skip "must run as root"
12004         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
12005                 skip_env "must have user_xattr"
12006
12007         [ -z "$(which setfattr 2>/dev/null)" ] &&
12008                 skip_env "could not find setfattr"
12009
12010         local testfile=$DIR/$tfile
12011
12012         touch $testfile
12013         echo "set/get xattr..."
12014         setfattr -n trusted.name1 -v value1 $testfile ||
12015                 error "setfattr -n trusted.name1=value1 $testfile failed"
12016         getfattr -n trusted.name1 $testfile 2> /dev/null |
12017           grep "trusted.name1=.value1" ||
12018                 error "$testfile missing trusted.name1=value1"
12019
12020         setfattr -n user.author1 -v author1 $testfile ||
12021                 error "setfattr -n user.author1=author1 $testfile failed"
12022         getfattr -n user.author1 $testfile 2> /dev/null |
12023           grep "user.author1=.author1" ||
12024                 error "$testfile missing trusted.author1=author1"
12025
12026         echo "listxattr..."
12027         setfattr -n trusted.name2 -v value2 $testfile ||
12028                 error "$testfile unable to set trusted.name2"
12029         setfattr -n trusted.name3 -v value3 $testfile ||
12030                 error "$testfile unable to set trusted.name3"
12031         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
12032             grep "trusted.name" | wc -l) -eq 3 ] ||
12033                 error "$testfile missing 3 trusted.name xattrs"
12034
12035         setfattr -n user.author2 -v author2 $testfile ||
12036                 error "$testfile unable to set user.author2"
12037         setfattr -n user.author3 -v author3 $testfile ||
12038                 error "$testfile unable to set user.author3"
12039         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12040             grep "user.author" | wc -l) -eq 3 ] ||
12041                 error "$testfile missing 3 user.author xattrs"
12042
12043         echo "remove xattr..."
12044         setfattr -x trusted.name1 $testfile ||
12045                 error "$testfile error deleting trusted.name1"
12046         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12047                 error "$testfile did not delete trusted.name1 xattr"
12048
12049         setfattr -x user.author1 $testfile ||
12050                 error "$testfile error deleting user.author1"
12051         echo "set lustre special xattr ..."
12052         $LFS setstripe -c1 $testfile
12053         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12054                 awk -F "=" '/trusted.lov/ { print $2 }' )
12055         setfattr -n "trusted.lov" -v $lovea $testfile ||
12056                 error "$testfile doesn't ignore setting trusted.lov again"
12057         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12058                 error "$testfile allow setting invalid trusted.lov"
12059         rm -f $testfile
12060 }
12061 run_test 102a "user xattr test =================================="
12062
12063 check_102b_layout() {
12064         local layout="$*"
12065         local testfile=$DIR/$tfile
12066
12067         echo "test layout '$layout'"
12068         $LFS setstripe $layout $testfile || error "setstripe failed"
12069         $LFS getstripe -y $testfile
12070
12071         echo "get/set/list trusted.lov xattr ..." # b=10930
12072         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12073         [[ "$value" =~ "trusted.lov" ]] ||
12074                 error "can't get trusted.lov from $testfile"
12075         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12076                 error "getstripe failed"
12077
12078         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12079
12080         value=$(cut -d= -f2 <<<$value)
12081         # LU-13168: truncated xattr should fail if short lov_user_md header
12082         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12083                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12084         for len in $lens; do
12085                 echo "setfattr $len $testfile.2"
12086                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12087                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12088         done
12089         local stripe_size=$($LFS getstripe -S $testfile.2)
12090         local stripe_count=$($LFS getstripe -c $testfile.2)
12091         [[ $stripe_size -eq 65536 ]] ||
12092                 error "stripe size $stripe_size != 65536"
12093         [[ $stripe_count -eq $stripe_count_orig ]] ||
12094                 error "stripe count $stripe_count != $stripe_count_orig"
12095         rm $testfile $testfile.2
12096 }
12097
12098 test_102b() {
12099         [ -z "$(which setfattr 2>/dev/null)" ] &&
12100                 skip_env "could not find setfattr"
12101         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12102
12103         # check plain layout
12104         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12105
12106         # and also check composite layout
12107         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12108
12109 }
12110 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12111
12112 test_102c() {
12113         [ -z "$(which setfattr 2>/dev/null)" ] &&
12114                 skip_env "could not find setfattr"
12115         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12116
12117         # b10930: get/set/list lustre.lov xattr
12118         echo "get/set/list lustre.lov xattr ..."
12119         test_mkdir $DIR/$tdir
12120         chown $RUNAS_ID $DIR/$tdir
12121         local testfile=$DIR/$tdir/$tfile
12122         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12123                 error "setstripe failed"
12124         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12125                 error "getstripe failed"
12126         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12127         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12128
12129         local testfile2=${testfile}2
12130         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12131                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12132
12133         $RUNAS $MCREATE $testfile2
12134         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12135         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12136         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12137         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12138         [ $stripe_count -eq $STRIPECOUNT ] ||
12139                 error "stripe count $stripe_count != $STRIPECOUNT"
12140 }
12141 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12142
12143 compare_stripe_info1() {
12144         local stripe_index_all_zero=true
12145
12146         for num in 1 2 3 4; do
12147                 for count in $(seq 1 $STRIPE_COUNT); do
12148                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12149                                 local size=$((STRIPE_SIZE * num))
12150                                 local file=file"$num-$offset-$count"
12151                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12152                                 [[ $stripe_size -ne $size ]] &&
12153                                     error "$file: size $stripe_size != $size"
12154                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12155                                 # allow fewer stripes to be created, ORI-601
12156                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12157                                     error "$file: count $stripe_count != $count"
12158                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12159                                 [[ $stripe_index -ne 0 ]] &&
12160                                         stripe_index_all_zero=false
12161                         done
12162                 done
12163         done
12164         $stripe_index_all_zero &&
12165                 error "all files are being extracted starting from OST index 0"
12166         return 0
12167 }
12168
12169 have_xattrs_include() {
12170         tar --help | grep -q xattrs-include &&
12171                 echo --xattrs-include="lustre.*"
12172 }
12173
12174 test_102d() {
12175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12176         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12177
12178         XINC=$(have_xattrs_include)
12179         setup_test102
12180         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12181         cd $DIR/$tdir/$tdir
12182         compare_stripe_info1
12183 }
12184 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12185
12186 test_102f() {
12187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12188         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12189
12190         XINC=$(have_xattrs_include)
12191         setup_test102
12192         test_mkdir $DIR/$tdir.restore
12193         cd $DIR
12194         tar cf - --xattrs $tdir | tar xf - \
12195                 -C $DIR/$tdir.restore --xattrs $XINC
12196         cd $DIR/$tdir.restore/$tdir
12197         compare_stripe_info1
12198 }
12199 run_test 102f "tar copy files, not keep osts"
12200
12201 grow_xattr() {
12202         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12203                 skip "must have user_xattr"
12204         [ -z "$(which setfattr 2>/dev/null)" ] &&
12205                 skip_env "could not find setfattr"
12206         [ -z "$(which getfattr 2>/dev/null)" ] &&
12207                 skip_env "could not find getfattr"
12208
12209         local xsize=${1:-1024}  # in bytes
12210         local file=$DIR/$tfile
12211         local value="$(generate_string $xsize)"
12212         local xbig=trusted.big
12213         local toobig=$2
12214
12215         touch $file
12216         log "save $xbig on $file"
12217         if [ -z "$toobig" ]
12218         then
12219                 setfattr -n $xbig -v $value $file ||
12220                         error "saving $xbig on $file failed"
12221         else
12222                 setfattr -n $xbig -v $value $file &&
12223                         error "saving $xbig on $file succeeded"
12224                 return 0
12225         fi
12226
12227         local orig=$(get_xattr_value $xbig $file)
12228         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12229
12230         local xsml=trusted.sml
12231         log "save $xsml on $file"
12232         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12233
12234         local new=$(get_xattr_value $xbig $file)
12235         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12236
12237         log "grow $xsml on $file"
12238         setfattr -n $xsml -v "$value" $file ||
12239                 error "growing $xsml on $file failed"
12240
12241         new=$(get_xattr_value $xbig $file)
12242         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12243         log "$xbig still valid after growing $xsml"
12244
12245         rm -f $file
12246 }
12247
12248 test_102h() { # bug 15777
12249         grow_xattr 1024
12250 }
12251 run_test 102h "grow xattr from inside inode to external block"
12252
12253 test_102ha() {
12254         large_xattr_enabled || skip_env "ea_inode feature disabled"
12255
12256         echo "setting xattr of max xattr size: $(max_xattr_size)"
12257         grow_xattr $(max_xattr_size)
12258
12259         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12260         echo "This should fail:"
12261         grow_xattr $(($(max_xattr_size) + 10)) 1
12262 }
12263 run_test 102ha "grow xattr from inside inode to external inode"
12264
12265 test_102i() { # bug 17038
12266         [ -z "$(which getfattr 2>/dev/null)" ] &&
12267                 skip "could not find getfattr"
12268
12269         touch $DIR/$tfile
12270         ln -s $DIR/$tfile $DIR/${tfile}link
12271         getfattr -n trusted.lov $DIR/$tfile ||
12272                 error "lgetxattr on $DIR/$tfile failed"
12273         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12274                 grep -i "no such attr" ||
12275                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12276         rm -f $DIR/$tfile $DIR/${tfile}link
12277 }
12278 run_test 102i "lgetxattr test on symbolic link ============"
12279
12280 test_102j() {
12281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12282         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12283
12284         XINC=$(have_xattrs_include)
12285         setup_test102 "$RUNAS"
12286         chown $RUNAS_ID $DIR/$tdir
12287         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12288         cd $DIR/$tdir/$tdir
12289         compare_stripe_info1 "$RUNAS"
12290 }
12291 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12292
12293 test_102k() {
12294         [ -z "$(which setfattr 2>/dev/null)" ] &&
12295                 skip "could not find setfattr"
12296
12297         touch $DIR/$tfile
12298         # b22187 just check that does not crash for regular file.
12299         setfattr -n trusted.lov $DIR/$tfile
12300         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12301         local test_kdir=$DIR/$tdir
12302         test_mkdir $test_kdir
12303         local default_size=$($LFS getstripe -S $test_kdir)
12304         local default_count=$($LFS getstripe -c $test_kdir)
12305         local default_offset=$($LFS getstripe -i $test_kdir)
12306         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12307                 error 'dir setstripe failed'
12308         setfattr -n trusted.lov $test_kdir
12309         local stripe_size=$($LFS getstripe -S $test_kdir)
12310         local stripe_count=$($LFS getstripe -c $test_kdir)
12311         local stripe_offset=$($LFS getstripe -i $test_kdir)
12312         [ $stripe_size -eq $default_size ] ||
12313                 error "stripe size $stripe_size != $default_size"
12314         [ $stripe_count -eq $default_count ] ||
12315                 error "stripe count $stripe_count != $default_count"
12316         [ $stripe_offset -eq $default_offset ] ||
12317                 error "stripe offset $stripe_offset != $default_offset"
12318         rm -rf $DIR/$tfile $test_kdir
12319 }
12320 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12321
12322 test_102l() {
12323         [ -z "$(which getfattr 2>/dev/null)" ] &&
12324                 skip "could not find getfattr"
12325
12326         # LU-532 trusted. xattr is invisible to non-root
12327         local testfile=$DIR/$tfile
12328
12329         touch $testfile
12330
12331         echo "listxattr as user..."
12332         chown $RUNAS_ID $testfile
12333         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12334             grep -q "trusted" &&
12335                 error "$testfile trusted xattrs are user visible"
12336
12337         return 0;
12338 }
12339 run_test 102l "listxattr size test =================================="
12340
12341 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12342         local path=$DIR/$tfile
12343         touch $path
12344
12345         listxattr_size_check $path || error "listattr_size_check $path failed"
12346 }
12347 run_test 102m "Ensure listxattr fails on small bufffer ========"
12348
12349 cleanup_test102
12350
12351 getxattr() { # getxattr path name
12352         # Return the base64 encoding of the value of xattr name on path.
12353         local path=$1
12354         local name=$2
12355
12356         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12357         # file: $path
12358         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12359         #
12360         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12361
12362         getfattr --absolute-names --encoding=base64 --name=$name $path |
12363                 awk -F= -v name=$name '$1 == name {
12364                         print substr($0, index($0, "=") + 1);
12365         }'
12366 }
12367
12368 test_102n() { # LU-4101 mdt: protect internal xattrs
12369         [ -z "$(which setfattr 2>/dev/null)" ] &&
12370                 skip "could not find setfattr"
12371         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12372         then
12373                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12374         fi
12375
12376         local file0=$DIR/$tfile.0
12377         local file1=$DIR/$tfile.1
12378         local xattr0=$TMP/$tfile.0
12379         local xattr1=$TMP/$tfile.1
12380         local namelist="lov lma lmv link fid version som hsm"
12381         local name
12382         local value
12383
12384         rm -rf $file0 $file1 $xattr0 $xattr1
12385         touch $file0 $file1
12386
12387         # Get 'before' xattrs of $file1.
12388         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12389
12390         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12391                 namelist+=" lfsck_namespace"
12392         for name in $namelist; do
12393                 # Try to copy xattr from $file0 to $file1.
12394                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12395
12396                 setfattr --name=trusted.$name --value="$value" $file1 ||
12397                         error "setxattr 'trusted.$name' failed"
12398
12399                 # Try to set a garbage xattr.
12400                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12401
12402                 if [[ x$name == "xlov" ]]; then
12403                         setfattr --name=trusted.lov --value="$value" $file1 &&
12404                         error "setxattr invalid 'trusted.lov' success"
12405                 else
12406                         setfattr --name=trusted.$name --value="$value" $file1 ||
12407                                 error "setxattr invalid 'trusted.$name' failed"
12408                 fi
12409
12410                 # Try to remove the xattr from $file1. We don't care if this
12411                 # appears to succeed or fail, we just don't want there to be
12412                 # any changes or crashes.
12413                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12414         done
12415
12416         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12417         then
12418                 name="lfsck_ns"
12419                 # Try to copy xattr from $file0 to $file1.
12420                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12421
12422                 setfattr --name=trusted.$name --value="$value" $file1 ||
12423                         error "setxattr 'trusted.$name' failed"
12424
12425                 # Try to set a garbage xattr.
12426                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12427
12428                 setfattr --name=trusted.$name --value="$value" $file1 ||
12429                         error "setxattr 'trusted.$name' failed"
12430
12431                 # Try to remove the xattr from $file1. We don't care if this
12432                 # appears to succeed or fail, we just don't want there to be
12433                 # any changes or crashes.
12434                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12435         fi
12436
12437         # Get 'after' xattrs of file1.
12438         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12439
12440         if ! diff $xattr0 $xattr1; then
12441                 error "before and after xattrs of '$file1' differ"
12442         fi
12443
12444         rm -rf $file0 $file1 $xattr0 $xattr1
12445
12446         return 0
12447 }
12448 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12449
12450 test_102p() { # LU-4703 setxattr did not check ownership
12451         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12452                 skip "MDS needs to be at least 2.5.56"
12453
12454         local testfile=$DIR/$tfile
12455
12456         touch $testfile
12457
12458         echo "setfacl as user..."
12459         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12460         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12461
12462         echo "setfattr as user..."
12463         setfacl -m "u:$RUNAS_ID:---" $testfile
12464         $RUNAS setfattr -x system.posix_acl_access $testfile
12465         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12466 }
12467 run_test 102p "check setxattr(2) correctly fails without permission"
12468
12469 test_102q() {
12470         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12471                 skip "MDS needs to be at least 2.6.92"
12472
12473         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12474 }
12475 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12476
12477 test_102r() {
12478         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12479                 skip "MDS needs to be at least 2.6.93"
12480
12481         touch $DIR/$tfile || error "touch"
12482         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12483         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12484         rm $DIR/$tfile || error "rm"
12485
12486         #normal directory
12487         mkdir -p $DIR/$tdir || error "mkdir"
12488         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12489         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12490         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12491                 error "$testfile error deleting user.author1"
12492         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12493                 grep "user.$(basename $tdir)" &&
12494                 error "$tdir did not delete user.$(basename $tdir)"
12495         rmdir $DIR/$tdir || error "rmdir"
12496
12497         #striped directory
12498         test_mkdir $DIR/$tdir
12499         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12500         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12501         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12502                 error "$testfile error deleting user.author1"
12503         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12504                 grep "user.$(basename $tdir)" &&
12505                 error "$tdir did not delete user.$(basename $tdir)"
12506         rmdir $DIR/$tdir || error "rm striped dir"
12507 }
12508 run_test 102r "set EAs with empty values"
12509
12510 test_102s() {
12511         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12512                 skip "MDS needs to be at least 2.11.52"
12513
12514         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12515
12516         save_lustre_params client "llite.*.xattr_cache" > $save
12517
12518         for cache in 0 1; do
12519                 lctl set_param llite.*.xattr_cache=$cache
12520
12521                 rm -f $DIR/$tfile
12522                 touch $DIR/$tfile || error "touch"
12523                 for prefix in lustre security system trusted user; do
12524                         # Note getxattr() may fail with 'Operation not
12525                         # supported' or 'No such attribute' depending
12526                         # on prefix and cache.
12527                         getfattr -n $prefix.n102s $DIR/$tfile &&
12528                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12529                 done
12530         done
12531
12532         restore_lustre_params < $save
12533 }
12534 run_test 102s "getting nonexistent xattrs should fail"
12535
12536 test_102t() {
12537         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12538                 skip "MDS needs to be at least 2.11.52"
12539
12540         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12541
12542         save_lustre_params client "llite.*.xattr_cache" > $save
12543
12544         for cache in 0 1; do
12545                 lctl set_param llite.*.xattr_cache=$cache
12546
12547                 for buf_size in 0 256; do
12548                         rm -f $DIR/$tfile
12549                         touch $DIR/$tfile || error "touch"
12550                         setfattr -n user.multiop $DIR/$tfile
12551                         $MULTIOP $DIR/$tfile oa$buf_size ||
12552                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12553                 done
12554         done
12555
12556         restore_lustre_params < $save
12557 }
12558 run_test 102t "zero length xattr values handled correctly"
12559
12560 run_acl_subtest()
12561 {
12562         local test=$LUSTRE/tests/acl/$1.test
12563         local tmp=$(mktemp -t $1-XXXXXX).test
12564         local bin=$2
12565         local dmn=$3
12566         local grp=$4
12567         local nbd=$5
12568         export LANG=C
12569
12570
12571         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12572         local sedgroups="-e s/:users/:$grp/g"
12573         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12574
12575         sed $sedusers $sedgroups < $test > $tmp
12576         stack_trap "rm -f $tmp"
12577         [[ -s $tmp ]] || error "sed failed to create test script"
12578
12579         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12580         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12581 }
12582
12583 test_103a() {
12584         [ "$UID" != 0 ] && skip "must run as root"
12585         $GSS && skip_env "could not run under gss"
12586         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12587                 skip_env "must have acl enabled"
12588         which setfacl || skip_env "could not find setfacl"
12589         remote_mds_nodsh && skip "remote MDS with nodsh"
12590
12591         local mdts=$(comma_list $(mdts_nodes))
12592         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12593
12594         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12595         stack_trap "[[ -z \"$saved\" ]] || \
12596                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12597
12598         ACLBIN=${ACLBIN:-"bin"}
12599         ACLDMN=${ACLDMN:-"daemon"}
12600         ACLGRP=${ACLGRP:-"users"}
12601         ACLNBD=${ACLNBD:-"nobody"}
12602
12603         if ! id $ACLBIN ||
12604            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12605                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12606                 ACLBIN=$USER0
12607                 if ! id $ACLBIN ; then
12608                         cat /etc/passwd
12609                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12610                 fi
12611         fi
12612         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12613            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12614                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12615                 ACLDMN=$USER1
12616                 if ! id $ACLDMN ; then
12617                         cat /etc/passwd
12618                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12619                 fi
12620         fi
12621         if ! getent group $ACLGRP; then
12622                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12623                 ACLGRP="$TSTUSR"
12624                 if ! getent group $ACLGRP; then
12625                         echo "cannot find group '$ACLGRP', adding it"
12626                         cat /etc/group
12627                         add_group 60000 $ACLGRP
12628                 fi
12629         fi
12630
12631         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12632         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12633         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12634
12635         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12636                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12637                 ACLGRP="$TSTUSR"
12638                 if ! getent group $ACLGRP; then
12639                         echo "cannot find group '$ACLGRP', adding it"
12640                         cat /etc/group
12641                         add_group 60000 $ACLGRP
12642                 fi
12643                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12644                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12645                         cat /etc/group
12646                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12647                 fi
12648         fi
12649
12650         gpasswd -a $ACLDMN $ACLBIN ||
12651                 error "setting client group failed"             # LU-5641
12652         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12653                 error "setting MDS group failed"                # LU-5641
12654
12655         declare -a identity_old
12656
12657         for ((num = 1; num <= $MDSCOUNT; num++)); do
12658                 switch_identity $num true || identity_old[$num]=$?
12659         done
12660
12661         SAVE_UMASK=$(umask)
12662         umask 0022
12663         mkdir -p $DIR/$tdir
12664         cd $DIR/$tdir
12665
12666         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12667         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12668         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12669         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12670         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12671         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12672         if ! id -u $ACLNBD ||
12673            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12674                 ACLNBD="nfsnobody"
12675                 if ! id -u $ACLNBD; then
12676                         ACLNBD=""
12677                 fi
12678         fi
12679         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12680                 add_group $(id -u $ACLNBD) $ACLNBD
12681                 if ! getent group $ACLNBD; then
12682                         ACLNBD=""
12683                 fi
12684         fi
12685         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12686            [[ -n "$ACLNBD" ]] && which setfattr; then
12687                 run_acl_subtest permissions_xattr \
12688                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12689         elif [[ -z "$ACLNBD" ]]; then
12690                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12691         else
12692                 echo "skip 'permission_xattr' test - missing setfattr command"
12693         fi
12694         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12695
12696         # inheritance test got from HP
12697         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12698         chmod +x make-tree || error "chmod +x failed"
12699         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12700         rm -f make-tree
12701
12702         echo "LU-974 ignore umask when acl is enabled..."
12703         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12704         if [ $MDSCOUNT -ge 2 ]; then
12705                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12706         fi
12707
12708         echo "LU-2561 newly created file is same size as directory..."
12709         if [ "$mds1_FSTYPE" != "zfs" ]; then
12710                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12711         else
12712                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12713         fi
12714
12715         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12716
12717         cd $SAVE_PWD
12718         umask $SAVE_UMASK
12719
12720         for ((num = 1; num <= $MDSCOUNT; num++)); do
12721                 if [[ "${identity_old[$num]}" == 1 ]]; then
12722                         switch_identity $num false || identity_old[$num]=$?
12723                 fi
12724         done
12725 }
12726 run_test 103a "acl test"
12727
12728 test_103b() {
12729         declare -a pids
12730         local U
12731
12732         stack_trap "rm -f $DIR/$tfile.*"
12733         for U in {0..511}; do
12734                 {
12735                 local O=$(printf "%04o" $U)
12736
12737                 umask $(printf "%04o" $((511 ^ $O)))
12738                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12739                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12740
12741                 (( $S == ($O & 0666) )) ||
12742                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12743
12744                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12745                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12746                 (( $S == ($O & 0666) )) ||
12747                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12748
12749                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12750                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12751                 (( $S == ($O & 0666) )) ||
12752                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12753                 rm -f $DIR/$tfile.[smp]$0
12754                 } &
12755                 local pid=$!
12756
12757                 # limit the concurrently running threads to 64. LU-11878
12758                 local idx=$((U % 64))
12759                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12760                 pids[idx]=$pid
12761         done
12762         wait
12763 }
12764 run_test 103b "umask lfs setstripe"
12765
12766 test_103c() {
12767         mkdir -p $DIR/$tdir
12768         cp -rp $DIR/$tdir $DIR/$tdir.bak
12769
12770         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12771                 error "$DIR/$tdir shouldn't contain default ACL"
12772         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12773                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12774         true
12775 }
12776 run_test 103c "'cp -rp' won't set empty acl"
12777
12778 test_103e() {
12779         local numacl
12780         local fileacl
12781         local saved_debug=$($LCTL get_param -n debug)
12782
12783         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12784                 skip "MDS needs to be at least 2.14.52"
12785
12786         large_xattr_enabled || skip_env "ea_inode feature disabled"
12787
12788         mkdir -p $DIR/$tdir
12789         # add big LOV EA to cause reply buffer overflow earlier
12790         $LFS setstripe -C 1000 $DIR/$tdir
12791         lctl set_param mdc.*-mdc*.stats=clear
12792
12793         $LCTL set_param debug=0
12794         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12795         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12796
12797         # add a large number of default ACLs (expect 8000+ for 2.13+)
12798         for U in {2..7000}; do
12799                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12800                         error "Able to add just $U default ACLs"
12801         done
12802         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12803         echo "$numacl default ACLs created"
12804
12805         stat $DIR/$tdir || error "Cannot stat directory"
12806         # check file creation
12807         touch $DIR/$tdir/$tfile ||
12808                 error "failed to create $tfile with $numacl default ACLs"
12809         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12810         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12811         echo "$fileacl ACLs were inherited"
12812         (( $fileacl == $numacl )) ||
12813                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12814         # check that new ACLs creation adds new ACLs to inherited ACLs
12815         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12816                 error "Cannot set new ACL"
12817         numacl=$((numacl + 1))
12818         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12819         (( $fileacl == $numacl )) ||
12820                 error "failed to add new ACL: $fileacl != $numacl as expected"
12821         # adds more ACLs to a file to reach their maximum at 8000+
12822         numacl=0
12823         for U in {20000..25000}; do
12824                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12825                 numacl=$((numacl + 1))
12826         done
12827         echo "Added $numacl more ACLs to the file"
12828         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12829         echo "Total $fileacl ACLs in file"
12830         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12831         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12832         rmdir $DIR/$tdir || error "Cannot remove directory"
12833 }
12834 run_test 103e "inheritance of big amount of default ACLs"
12835
12836 test_103f() {
12837         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12838                 skip "MDS needs to be at least 2.14.51"
12839
12840         large_xattr_enabled || skip_env "ea_inode feature disabled"
12841
12842         # enable changelog to consume more internal MDD buffers
12843         changelog_register
12844
12845         mkdir -p $DIR/$tdir
12846         # add big LOV EA
12847         $LFS setstripe -C 1000 $DIR/$tdir
12848         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12849         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12850         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12851         rmdir $DIR/$tdir || error "Cannot remove directory"
12852 }
12853 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12854
12855 test_104a() {
12856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12857
12858         touch $DIR/$tfile
12859         lfs df || error "lfs df failed"
12860         lfs df -ih || error "lfs df -ih failed"
12861         lfs df -h $DIR || error "lfs df -h $DIR failed"
12862         lfs df -i $DIR || error "lfs df -i $DIR failed"
12863         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12864         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12865
12866         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12867         lctl --device %$OSC deactivate
12868         lfs df || error "lfs df with deactivated OSC failed"
12869         lctl --device %$OSC activate
12870         # wait the osc back to normal
12871         wait_osc_import_ready client ost
12872
12873         lfs df || error "lfs df with reactivated OSC failed"
12874         rm -f $DIR/$tfile
12875 }
12876 run_test 104a "lfs df [-ih] [path] test ========================="
12877
12878 test_104b() {
12879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12880         [ $RUNAS_ID -eq $UID ] &&
12881                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12882
12883         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12884                         grep "Permission denied" | wc -l)))
12885         if [ $denied_cnt -ne 0 ]; then
12886                 error "lfs check servers test failed"
12887         fi
12888 }
12889 run_test 104b "$RUNAS lfs check servers test ===================="
12890
12891 #
12892 # Verify $1 is within range of $2.
12893 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12894 # $1 is <= 2% of $2. Else Fail.
12895 #
12896 value_in_range() {
12897         # Strip all units (M, G, T)
12898         actual=$(echo $1 | tr -d A-Z)
12899         expect=$(echo $2 | tr -d A-Z)
12900
12901         expect_lo=$(($expect * 98 / 100)) # 2% below
12902         expect_hi=$(($expect * 102 / 100)) # 2% above
12903
12904         # permit 2% drift above and below
12905         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12906 }
12907
12908 test_104c() {
12909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12910         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12911
12912         local ost_param="osd-zfs.$FSNAME-OST0000."
12913         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12914         local ofacets=$(get_facets OST)
12915         local mfacets=$(get_facets MDS)
12916         local saved_ost_blocks=
12917         local saved_mdt_blocks=
12918
12919         echo "Before recordsize change"
12920         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12921         df=($(df -h | grep "$MOUNT"$))
12922
12923         # For checking.
12924         echo "lfs output : ${lfs_df[*]}"
12925         echo "df  output : ${df[*]}"
12926
12927         for facet in ${ofacets//,/ }; do
12928                 if [ -z $saved_ost_blocks ]; then
12929                         saved_ost_blocks=$(do_facet $facet \
12930                                 lctl get_param -n $ost_param.blocksize)
12931                         echo "OST Blocksize: $saved_ost_blocks"
12932                 fi
12933                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12934                 do_facet $facet zfs set recordsize=32768 $ost
12935         done
12936
12937         # BS too small. Sufficient for functional testing.
12938         for facet in ${mfacets//,/ }; do
12939                 if [ -z $saved_mdt_blocks ]; then
12940                         saved_mdt_blocks=$(do_facet $facet \
12941                                 lctl get_param -n $mdt_param.blocksize)
12942                         echo "MDT Blocksize: $saved_mdt_blocks"
12943                 fi
12944                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12945                 do_facet $facet zfs set recordsize=32768 $mdt
12946         done
12947
12948         # Give new values chance to reflect change
12949         sleep 2
12950
12951         echo "After recordsize change"
12952         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12953         df_after=($(df -h | grep "$MOUNT"$))
12954
12955         # For checking.
12956         echo "lfs output : ${lfs_df_after[*]}"
12957         echo "df  output : ${df_after[*]}"
12958
12959         # Verify lfs df
12960         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12961                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12962         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12963                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12964         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12965                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12966
12967         # Verify df
12968         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12969                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12970         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12971                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12972         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12973                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12974
12975         # Restore MDT recordize back to original
12976         for facet in ${mfacets//,/ }; do
12977                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12978                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12979         done
12980
12981         # Restore OST recordize back to original
12982         for facet in ${ofacets//,/ }; do
12983                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12984                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12985         done
12986
12987         return 0
12988 }
12989 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12990
12991 test_104d() {
12992         (( $RUNAS_ID != $UID )) ||
12993                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12994
12995         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12996                 skip "lustre version doesn't support lctl dl with non-root"
12997
12998         # debugfs only allows root users to access files, so the
12999         # previous move of the "devices" file to debugfs broke
13000         # "lctl dl" for non-root users. The LU-9680 Netlink
13001         # interface again allows non-root users to list devices.
13002         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
13003                 error "lctl dl doesn't work for non root"
13004
13005         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
13006         [ "$ost_count" -eq $OSTCOUNT ]  ||
13007                 error "lctl dl reports wrong number of OST devices"
13008
13009         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
13010         [ "$mdt_count" -eq $MDSCOUNT ]  ||
13011                 error "lctl dl reports wrong number of MDT devices"
13012 }
13013 run_test 104d "$RUNAS lctl dl test"
13014
13015 test_105a() {
13016         # doesn't work on 2.4 kernels
13017         touch $DIR/$tfile
13018         if $(flock_is_enabled); then
13019                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
13020         else
13021                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
13022         fi
13023         rm -f $DIR/$tfile
13024 }
13025 run_test 105a "flock when mounted without -o flock test ========"
13026
13027 test_105b() {
13028         touch $DIR/$tfile
13029         if $(flock_is_enabled); then
13030                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
13031         else
13032                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13033         fi
13034         rm -f $DIR/$tfile
13035 }
13036 run_test 105b "fcntl when mounted without -o flock test ========"
13037
13038 test_105c() {
13039         touch $DIR/$tfile
13040         if $(flock_is_enabled); then
13041                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13042         else
13043                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13044         fi
13045         rm -f $DIR/$tfile
13046 }
13047 run_test 105c "lockf when mounted without -o flock test"
13048
13049 test_105d() { # bug 15924
13050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13051
13052         test_mkdir $DIR/$tdir
13053         flock_is_enabled || skip_env "mount w/o flock enabled"
13054         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13055         $LCTL set_param fail_loc=0x80000315
13056         flocks_test 2 $DIR/$tdir
13057 }
13058 run_test 105d "flock race (should not freeze) ========"
13059
13060 test_105e() { # bug 22660 && 22040
13061         flock_is_enabled || skip_env "mount w/o flock enabled"
13062
13063         touch $DIR/$tfile
13064         flocks_test 3 $DIR/$tfile
13065 }
13066 run_test 105e "Two conflicting flocks from same process"
13067
13068 wait_end() {
13069         echo $*
13070         while :; do
13071                 [ -f $TMP/${tfile}_sTOP ] && return
13072                 sleep 1
13073         done
13074 }
13075
13076 test_105f() {
13077         flock_is_enabled || skip_env "mount w/o flock enabled"
13078
13079         local pmax=$(ulimit -u)
13080         local i=0
13081         touch $DIR/$tfile
13082         [ $pmax -gt 20 ] && pmax=20
13083         for((i=0; i <= $pmax; i++)) {
13084                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13085         }
13086         for((i=0; i <= 10; i++)) {
13087                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13088                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13089                 [ $locks -ge $pmax ] && break
13090                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13091                 sleep 1
13092         }
13093         touch $TMP/${tfile}_sTOP
13094         wait
13095         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13096 }
13097 run_test 105f "Enqueue same range flocks"
13098
13099 test_106() { #bug 10921
13100         test_mkdir $DIR/$tdir
13101         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13102         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13103 }
13104 run_test 106 "attempt exec of dir followed by chown of that dir"
13105
13106 test_107() {
13107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13108
13109         CDIR=`pwd`
13110         local file=core
13111
13112         cd $DIR
13113         rm -f $file
13114
13115         local save_pattern=$(sysctl -n kernel.core_pattern)
13116         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13117         sysctl -w kernel.core_pattern=$file
13118         sysctl -w kernel.core_uses_pid=0
13119
13120         ulimit -c unlimited
13121         sleep 60 &
13122         SLEEPPID=$!
13123
13124         sleep 1
13125
13126         kill -s 11 $SLEEPPID
13127         wait $SLEEPPID
13128         if [ -e $file ]; then
13129                 size=`stat -c%s $file`
13130                 [ $size -eq 0 ] && error "Fail to create core file $file"
13131         else
13132                 error "Fail to create core file $file"
13133         fi
13134         rm -f $file
13135         sysctl -w kernel.core_pattern=$save_pattern
13136         sysctl -w kernel.core_uses_pid=$save_uses_pid
13137         cd $CDIR
13138 }
13139 run_test 107 "Coredump on SIG"
13140
13141 test_110() {
13142         test_mkdir $DIR/$tdir
13143         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13144         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13145                 error "mkdir with 256 char should fail, but did not"
13146         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13147                 error "create with 255 char failed"
13148         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13149                 error "create with 256 char should fail, but did not"
13150
13151         ls -l $DIR/$tdir
13152         rm -rf $DIR/$tdir
13153 }
13154 run_test 110 "filename length checking"
13155
13156 test_116a() { # was previously test_116()
13157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13158         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13159         remote_mds_nodsh && skip "remote MDS with nodsh"
13160
13161         echo -n "Free space priority "
13162         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13163                 head -n1
13164         declare -a AVAIL
13165         free_min_max
13166
13167         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13168         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13169         stack_trap simple_cleanup_common
13170
13171         # Check if we need to generate uneven OSTs
13172         test_mkdir -p $DIR/$tdir/OST${MINI}
13173         local FILL=$((MINV / 4))
13174         local DIFF=$((MAXV - MINV))
13175         local DIFF2=$((DIFF * 100 / MINV))
13176
13177         local threshold=$(do_facet $SINGLEMDS \
13178                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13179         threshold=${threshold%%%}
13180         echo -n "Check for uneven OSTs: "
13181         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13182
13183         if [[ $DIFF2 -gt $threshold ]]; then
13184                 echo "ok"
13185                 echo "Don't need to fill OST$MINI"
13186         else
13187                 # generate uneven OSTs. Write 2% over the QOS threshold value
13188                 echo "no"
13189                 DIFF=$((threshold - DIFF2 + 2))
13190                 DIFF2=$((MINV * DIFF / 100))
13191                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13192                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13193                         error "setstripe failed"
13194                 DIFF=$((DIFF2 / 2048))
13195                 i=0
13196                 while [ $i -lt $DIFF ]; do
13197                         i=$((i + 1))
13198                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13199                                 bs=2M count=1 2>/dev/null
13200                         echo -n .
13201                 done
13202                 echo .
13203                 sync
13204                 sleep_maxage
13205                 free_min_max
13206         fi
13207
13208         DIFF=$((MAXV - MINV))
13209         DIFF2=$((DIFF * 100 / MINV))
13210         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13211         if [ $DIFF2 -gt $threshold ]; then
13212                 echo "ok"
13213         else
13214                 skip "QOS imbalance criteria not met"
13215         fi
13216
13217         MINI1=$MINI
13218         MINV1=$MINV
13219         MAXI1=$MAXI
13220         MAXV1=$MAXV
13221
13222         # now fill using QOS
13223         $LFS setstripe -c 1 $DIR/$tdir
13224         FILL=$((FILL / 200))
13225         if [ $FILL -gt 600 ]; then
13226                 FILL=600
13227         fi
13228         echo "writing $FILL files to QOS-assigned OSTs"
13229         i=0
13230         while [ $i -lt $FILL ]; do
13231                 i=$((i + 1))
13232                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13233                         count=1 2>/dev/null
13234                 echo -n .
13235         done
13236         echo "wrote $i 200k files"
13237         sync
13238         sleep_maxage
13239
13240         echo "Note: free space may not be updated, so measurements might be off"
13241         free_min_max
13242         DIFF2=$((MAXV - MINV))
13243         echo "free space delta: orig $DIFF final $DIFF2"
13244         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13245         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13246         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13247         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13248         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13249         if [[ $DIFF -gt 0 ]]; then
13250                 FILL=$((DIFF2 * 100 / DIFF - 100))
13251                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13252         fi
13253
13254         # Figure out which files were written where
13255         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13256                awk '/'$MINI1': / {print $2; exit}')
13257         echo $UUID
13258         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13259         echo "$MINC files created on smaller OST $MINI1"
13260         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13261                awk '/'$MAXI1': / {print $2; exit}')
13262         echo $UUID
13263         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13264         echo "$MAXC files created on larger OST $MAXI1"
13265         if [[ $MINC -gt 0 ]]; then
13266                 FILL=$((MAXC * 100 / MINC - 100))
13267                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13268         fi
13269         [[ $MAXC -gt $MINC ]] ||
13270                 error_ignore LU-9 "stripe QOS didn't balance free space"
13271 }
13272 run_test 116a "stripe QOS: free space balance ==================="
13273
13274 test_116b() { # LU-2093
13275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13276         remote_mds_nodsh && skip "remote MDS with nodsh"
13277
13278 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13279         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13280                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13281         [ -z "$old_rr" ] && skip "no QOS"
13282         do_facet $SINGLEMDS lctl set_param \
13283                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13284         mkdir -p $DIR/$tdir
13285         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13286         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13287         do_facet $SINGLEMDS lctl set_param fail_loc=0
13288         rm -rf $DIR/$tdir
13289         do_facet $SINGLEMDS lctl set_param \
13290                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13291 }
13292 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13293
13294 test_117() # bug 10891
13295 {
13296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13297
13298         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13299         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13300         lctl set_param fail_loc=0x21e
13301         > $DIR/$tfile || error "truncate failed"
13302         lctl set_param fail_loc=0
13303         echo "Truncate succeeded."
13304         rm -f $DIR/$tfile
13305 }
13306 run_test 117 "verify osd extend =========="
13307
13308 NO_SLOW_RESENDCOUNT=4
13309 export OLD_RESENDCOUNT=""
13310 set_resend_count () {
13311         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13312         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13313         lctl set_param -n $PROC_RESENDCOUNT $1
13314         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13315 }
13316
13317 # for reduce test_118* time (b=14842)
13318 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13319
13320 # Reset async IO behavior after error case
13321 reset_async() {
13322         FILE=$DIR/reset_async
13323
13324         # Ensure all OSCs are cleared
13325         $LFS setstripe -c -1 $FILE
13326         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13327         sync
13328         rm $FILE
13329 }
13330
13331 test_118a() #bug 11710
13332 {
13333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13334
13335         reset_async
13336
13337         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13338         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13339         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13340
13341         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13342                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13343                 return 1;
13344         fi
13345         rm -f $DIR/$tfile
13346 }
13347 run_test 118a "verify O_SYNC works =========="
13348
13349 test_118b()
13350 {
13351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13352         remote_ost_nodsh && skip "remote OST with nodsh"
13353
13354         reset_async
13355
13356         #define OBD_FAIL_SRV_ENOENT 0x217
13357         set_nodes_failloc "$(osts_nodes)" 0x217
13358         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13359         RC=$?
13360         set_nodes_failloc "$(osts_nodes)" 0
13361         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13362         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13363                     grep -c writeback)
13364
13365         if [[ $RC -eq 0 ]]; then
13366                 error "Must return error due to dropped pages, rc=$RC"
13367                 return 1;
13368         fi
13369
13370         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13371                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13372                 return 1;
13373         fi
13374
13375         echo "Dirty pages not leaked on ENOENT"
13376
13377         # Due to the above error the OSC will issue all RPCs syncronously
13378         # until a subsequent RPC completes successfully without error.
13379         $MULTIOP $DIR/$tfile Ow4096yc
13380         rm -f $DIR/$tfile
13381
13382         return 0
13383 }
13384 run_test 118b "Reclaim dirty pages on fatal error =========="
13385
13386 test_118c()
13387 {
13388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13389
13390         # for 118c, restore the original resend count, LU-1940
13391         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13392                                 set_resend_count $OLD_RESENDCOUNT
13393         remote_ost_nodsh && skip "remote OST with nodsh"
13394
13395         reset_async
13396
13397         #define OBD_FAIL_OST_EROFS               0x216
13398         set_nodes_failloc "$(osts_nodes)" 0x216
13399
13400         # multiop should block due to fsync until pages are written
13401         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13402         MULTIPID=$!
13403         sleep 1
13404
13405         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13406                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13407         fi
13408
13409         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13410                     grep -c writeback)
13411         if [[ $WRITEBACK -eq 0 ]]; then
13412                 error "No page in writeback, writeback=$WRITEBACK"
13413         fi
13414
13415         set_nodes_failloc "$(osts_nodes)" 0
13416         wait $MULTIPID
13417         RC=$?
13418         if [[ $RC -ne 0 ]]; then
13419                 error "Multiop fsync failed, rc=$RC"
13420         fi
13421
13422         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13423         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13424                     grep -c writeback)
13425         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13426                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13427         fi
13428
13429         rm -f $DIR/$tfile
13430         echo "Dirty pages flushed via fsync on EROFS"
13431         return 0
13432 }
13433 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13434
13435 # continue to use small resend count to reduce test_118* time (b=14842)
13436 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13437
13438 test_118d()
13439 {
13440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13441         remote_ost_nodsh && skip "remote OST with nodsh"
13442
13443         reset_async
13444
13445         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13446         set_nodes_failloc "$(osts_nodes)" 0x214
13447         # multiop should block due to fsync until pages are written
13448         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13449         MULTIPID=$!
13450         sleep 1
13451
13452         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13453                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13454         fi
13455
13456         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13457                     grep -c writeback)
13458         if [[ $WRITEBACK -eq 0 ]]; then
13459                 error "No page in writeback, writeback=$WRITEBACK"
13460         fi
13461
13462         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13463         set_nodes_failloc "$(osts_nodes)" 0
13464
13465         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13466         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13467                     grep -c writeback)
13468         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13469                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13470         fi
13471
13472         rm -f $DIR/$tfile
13473         echo "Dirty pages gaurenteed flushed via fsync"
13474         return 0
13475 }
13476 run_test 118d "Fsync validation inject a delay of the bulk =========="
13477
13478 test_118f() {
13479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13480
13481         reset_async
13482
13483         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13484         lctl set_param fail_loc=0x8000040a
13485
13486         # Should simulate EINVAL error which is fatal
13487         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13488         RC=$?
13489         if [[ $RC -eq 0 ]]; then
13490                 error "Must return error due to dropped pages, rc=$RC"
13491         fi
13492
13493         lctl set_param fail_loc=0x0
13494
13495         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13496         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13497         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13498                     grep -c writeback)
13499         if [[ $LOCKED -ne 0 ]]; then
13500                 error "Locked pages remain in cache, locked=$LOCKED"
13501         fi
13502
13503         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13504                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13505         fi
13506
13507         rm -f $DIR/$tfile
13508         echo "No pages locked after fsync"
13509
13510         reset_async
13511         return 0
13512 }
13513 run_test 118f "Simulate unrecoverable OSC side error =========="
13514
13515 test_118g() {
13516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13517
13518         reset_async
13519
13520         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13521         lctl set_param fail_loc=0x406
13522
13523         # simulate local -ENOMEM
13524         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13525         RC=$?
13526
13527         lctl set_param fail_loc=0
13528         if [[ $RC -eq 0 ]]; then
13529                 error "Must return error due to dropped pages, rc=$RC"
13530         fi
13531
13532         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13533         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13534         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13535                         grep -c writeback)
13536         if [[ $LOCKED -ne 0 ]]; then
13537                 error "Locked pages remain in cache, locked=$LOCKED"
13538         fi
13539
13540         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13541                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13542         fi
13543
13544         rm -f $DIR/$tfile
13545         echo "No pages locked after fsync"
13546
13547         reset_async
13548         return 0
13549 }
13550 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13551
13552 test_118h() {
13553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13554         remote_ost_nodsh && skip "remote OST with nodsh"
13555
13556         reset_async
13557
13558         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13559         set_nodes_failloc "$(osts_nodes)" 0x20e
13560         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13561         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13562         RC=$?
13563
13564         set_nodes_failloc "$(osts_nodes)" 0
13565         if [[ $RC -eq 0 ]]; then
13566                 error "Must return error due to dropped pages, rc=$RC"
13567         fi
13568
13569         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13570         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13571         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13572                     grep -c writeback)
13573         if [[ $LOCKED -ne 0 ]]; then
13574                 error "Locked pages remain in cache, locked=$LOCKED"
13575         fi
13576
13577         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13578                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13579         fi
13580
13581         rm -f $DIR/$tfile
13582         echo "No pages locked after fsync"
13583
13584         return 0
13585 }
13586 run_test 118h "Verify timeout in handling recoverables errors  =========="
13587
13588 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13589
13590 test_118i() {
13591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13592         remote_ost_nodsh && skip "remote OST with nodsh"
13593
13594         reset_async
13595
13596         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13597         set_nodes_failloc "$(osts_nodes)" 0x20e
13598
13599         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13600         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13601         PID=$!
13602         sleep 5
13603         set_nodes_failloc "$(osts_nodes)" 0
13604
13605         wait $PID
13606         RC=$?
13607         if [[ $RC -ne 0 ]]; then
13608                 error "got error, but should be not, rc=$RC"
13609         fi
13610
13611         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13612         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13613         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13614         if [[ $LOCKED -ne 0 ]]; then
13615                 error "Locked pages remain in cache, locked=$LOCKED"
13616         fi
13617
13618         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13619                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13620         fi
13621
13622         rm -f $DIR/$tfile
13623         echo "No pages locked after fsync"
13624
13625         return 0
13626 }
13627 run_test 118i "Fix error before timeout in recoverable error  =========="
13628
13629 [ "$SLOW" = "no" ] && set_resend_count 4
13630
13631 test_118j() {
13632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13633         remote_ost_nodsh && skip "remote OST with nodsh"
13634
13635         reset_async
13636
13637         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13638         set_nodes_failloc "$(osts_nodes)" 0x220
13639
13640         # return -EIO from OST
13641         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13642         RC=$?
13643         set_nodes_failloc "$(osts_nodes)" 0x0
13644         if [[ $RC -eq 0 ]]; then
13645                 error "Must return error due to dropped pages, rc=$RC"
13646         fi
13647
13648         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13649         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13650         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13651         if [[ $LOCKED -ne 0 ]]; then
13652                 error "Locked pages remain in cache, locked=$LOCKED"
13653         fi
13654
13655         # in recoverable error on OST we want resend and stay until it finished
13656         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13657                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13658         fi
13659
13660         rm -f $DIR/$tfile
13661         echo "No pages locked after fsync"
13662
13663         return 0
13664 }
13665 run_test 118j "Simulate unrecoverable OST side error =========="
13666
13667 test_118k()
13668 {
13669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13670         remote_ost_nodsh && skip "remote OSTs with nodsh"
13671
13672         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13673         set_nodes_failloc "$(osts_nodes)" 0x20e
13674         test_mkdir $DIR/$tdir
13675
13676         for ((i=0;i<10;i++)); do
13677                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13678                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13679                 SLEEPPID=$!
13680                 sleep 0.500s
13681                 kill $SLEEPPID
13682                 wait $SLEEPPID
13683         done
13684
13685         set_nodes_failloc "$(osts_nodes)" 0
13686         rm -rf $DIR/$tdir
13687 }
13688 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13689
13690 test_118l() # LU-646
13691 {
13692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13693
13694         test_mkdir $DIR/$tdir
13695         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13696         rm -rf $DIR/$tdir
13697 }
13698 run_test 118l "fsync dir"
13699
13700 test_118m() # LU-3066
13701 {
13702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13703
13704         test_mkdir $DIR/$tdir
13705         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13706         rm -rf $DIR/$tdir
13707 }
13708 run_test 118m "fdatasync dir ========="
13709
13710 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13711
13712 test_118n()
13713 {
13714         local begin
13715         local end
13716
13717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13718         remote_ost_nodsh && skip "remote OSTs with nodsh"
13719
13720         # Sleep to avoid a cached response.
13721         #define OBD_STATFS_CACHE_SECONDS 1
13722         sleep 2
13723
13724         # Inject a 10 second delay in the OST_STATFS handler.
13725         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13726         set_nodes_failloc "$(osts_nodes)" 0x242
13727
13728         begin=$SECONDS
13729         stat --file-system $MOUNT > /dev/null
13730         end=$SECONDS
13731
13732         set_nodes_failloc "$(osts_nodes)" 0
13733
13734         if ((end - begin > 20)); then
13735             error "statfs took $((end - begin)) seconds, expected 10"
13736         fi
13737 }
13738 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13739
13740 dio_readv_writev_support()
13741 {
13742         # Kernels after 3.16 work:
13743         (( $(version_code $(uname -r)) >= $(version_code 3.16) ))
13744                 return 0
13745         # Lustre with LU-17524 works:
13746         (( $OST1_VERSION > $(version_code 2.15.61.141) ))
13747                 return 0
13748
13749         skip "need readv/writev with O_DIRECT support"
13750 }
13751
13752 test_119a() # bug 11737
13753 {
13754         BSIZE=$((512 * 1024))
13755         directio write $DIR/$tfile 0 1 $BSIZE
13756         # We ask to read two blocks, which is more than a file size.
13757         # directio will indicate an error when requested and actual
13758         # sizes aren't equeal (a normal situation in this case) and
13759         # print actual read amount.
13760         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13761         if [ "$NOB" != "$BSIZE" ]; then
13762                 error "read $NOB bytes instead of $BSIZE"
13763         fi
13764         rm -f $DIR/$tfile
13765 }
13766 run_test 119a "Short directIO read must return actual read amount"
13767
13768 test_119b() # bug 11737
13769 {
13770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13771
13772         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13773         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13774         sync
13775         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13776                 error "direct read failed"
13777         rm -f $DIR/$tfile
13778 }
13779 run_test 119b "Sparse directIO read must return actual read amount"
13780
13781 test_119c() # bug 13099
13782 {
13783         BSIZE=1048576
13784         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13785         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13786         rm -f $DIR/$tfile
13787 }
13788 run_test 119c "Testing for direct read hitting hole"
13789
13790 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13791 # Maloo test history
13792
13793 test_119e()
13794 {
13795         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13796                 skip "Need server version at least 2.15.58"
13797         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13798
13799         local stripe_size=$((1024 * 1024)) #1 MiB
13800         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13801         local file_size=$((25 * stripe_size))
13802         local bsizes
13803
13804         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13805         stack_trap "rm -f $DIR/$tfile*"
13806
13807         # Just a bit bigger than the largest size in the test set below
13808         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13809                 error "buffered i/o to create file failed"
13810
13811         # trivial test of unaligned DIO
13812         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13813                 iflag=direct oflag=direct ||
13814                 error "trivial unaligned dio failed"
13815
13816         # Test of disabling unaligned DIO support
13817         $LCTL set_param llite.*.unaligned_dio=0
13818         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13819         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13820         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13821                 iflag=direct oflag=direct &&
13822                 error "unaligned dio succeeded when disabled"
13823         $LCTL set_param llite.*.unaligned_dio=1
13824
13825         # Clean up before next part of test
13826         rm -f $DIR/$tfile.2
13827
13828         if zfs_or_rotational; then
13829                 # DIO on ZFS can take up to 2 seconds per IO
13830                 # rotational is better, but still slow.
13831                 # Limit testing on those media to larger sizes
13832                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13833                         $((stripe_size + 1024))"
13834         else
13835                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13836                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13837                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13838                         $((stripe_size - 1)) $stripe_size \
13839                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13840                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13841         fi
13842
13843         for bs in $bsizes; do
13844                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13845                 echo "Read/write with DIO at size $bs"
13846                 # Read and write with DIO from source to dest
13847                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13848                         iflag=direct oflag=direct ||
13849                         error "dio failed"
13850
13851                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13852                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13853                         error "size incorrect, file copy read/write bsize: $bs"
13854                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13855                         error "files differ, bsize $bs"
13856                 rm -f $DIR/$tfile.2
13857         done
13858 }
13859 run_test 119e "Basic tests of dio read and write at various sizes"
13860
13861 test_119f()
13862 {
13863         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13864
13865         local stripe_size=$((1024 * 1024)) #1 MiB
13866         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13867         local file_size=$((25 * stripe_size))
13868         local bsizes
13869
13870         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13871         stack_trap "rm -f $DIR/$tfile*"
13872
13873         # Just a bit bigger than the largest size in the test set below
13874         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13875                 error "buffered i/o to create file failed"
13876
13877         if zfs_or_rotational; then
13878                 # DIO on ZFS can take up to 2 seconds per IO
13879                 # rotational is better, but still slow.
13880                 # Limit testing on those media to larger sizes
13881                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13882                         $((stripe_size + 1024))"
13883         else
13884                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13885                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13886                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13887                         $((stripe_size - 1)) $stripe_size \
13888                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13889                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13890         fi
13891
13892         for bs in $bsizes; do
13893                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13894                 # Read and write with DIO from source to dest in two
13895                 # threads - should give correct copy of file
13896
13897                 echo "bs: $bs"
13898                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13899                         oflag=direct conv=notrunc &
13900                 pid_dio1=$!
13901                 # Note block size is different here for a more interesting race
13902                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13903                         iflag=direct oflag=direct conv=notrunc &
13904                 pid_dio2=$!
13905                 wait $pid_dio1
13906                 rc1=$?
13907                 wait $pid_dio2
13908                 rc2=$?
13909                 if (( rc1 != 0 )); then
13910                         error "dio copy 1 w/bsize $bs failed: $rc1"
13911                 fi
13912                 if (( rc2 != 0 )); then
13913                         error "dio copy 2 w/bsize $bs failed: $rc2"
13914                 fi
13915
13916
13917                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13918                         error "size incorrect, file copy read/write bsize: $bs"
13919                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13920                         error "files differ, bsize $bs"
13921                 rm -f $DIR/$tfile.2
13922         done
13923 }
13924 run_test 119f "dio vs dio race"
13925
13926 test_119g()
13927 {
13928         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13929
13930         local stripe_size=$((1024 * 1024)) #1 MiB
13931         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13932         local file_size=$((25 * stripe_size))
13933         local bsizes
13934
13935         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13936         stack_trap "rm -f $DIR/$tfile*"
13937
13938         # Just a bit bigger than the largest size in the test set below
13939         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13940                 error "buffered i/o to create file failed"
13941
13942         if zfs_or_rotational; then
13943                 # DIO on ZFS can take up to 2 seconds per IO
13944                 # rotational is better, but still slow.
13945                 # Limit testing on those media to larger sizes
13946                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13947                         $((stripe_size + 1024))"
13948         else
13949                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13950                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13951                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13952                         $((stripe_size - 1)) $stripe_size \
13953                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13954                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13955         fi
13956
13957         for bs in $bsizes; do
13958                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13959                 echo "bs: $bs"
13960                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13961                         oflag=direct conv=notrunc &
13962                 pid_dio1=$!
13963                 # Buffered I/O with similar but not the same block size
13964                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13965                 pid_bio2=$!
13966                 wait $pid_dio1
13967                 rc1=$?
13968                 wait $pid_bio2
13969                 rc2=$?
13970                 if (( rc1 != 0 )); then
13971                         error "dio copy 1 w/bsize $bs failed: $rc1"
13972                 fi
13973                 if (( rc2 != 0 )); then
13974                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13975                 fi
13976
13977                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13978                         error "size incorrect"
13979                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13980                         error "files differ, bsize $bs"
13981                 rm -f $DIR/$tfile.2
13982         done
13983 }
13984 run_test 119g "dio vs buffered I/O race"
13985
13986 test_119h()
13987 {
13988         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13989
13990         local stripe_size=$((1024 * 1024)) #1 MiB
13991         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13992         local file_size=$((25 * stripe_size))
13993         local bsizes
13994
13995         stack_trap "rm -f $DIR/$tfile.*"
13996
13997         if zfs_or_rotational; then
13998                 # DIO on ZFS can take up to 2 seconds per IO
13999                 # rotational is better, but still slow.
14000                 # Limit testing on those media to larger sizes
14001                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14002                         $((stripe_size + 1024))"
14003         else
14004                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14005                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14006                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14007                         $((stripe_size - 1)) $stripe_size \
14008                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14009                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14010         fi
14011
14012         for bs in $bsizes; do
14013                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14014                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14015                 echo "unaligned writes of blocksize: $bs"
14016                 # Write a file with unaligned DIO and regular DIO, and compare
14017                 # them
14018                 # with 'u', multiop randomly unaligns the io from the buffer
14019                 $MULTIOP $DIR/$tfile.1 \
14020                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
14021                         error "multiop memory unaligned write failed, $bs"
14022                 $MULTIOP $DIR/$tfile.2 \
14023                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
14024                         error "multiop memory aligned write failed, $bs"
14025
14026                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14027                         error "files differ, bsize $bs"
14028                 rm -f $DIR/$tfile.*
14029         done
14030
14031         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14032         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
14033                 error "dd to create source file for read failed"
14034
14035         # Just a few quick tests to make sure unaligned DIO reads don't crash
14036         for bs in $bsizes; do
14037
14038                 echo "unaligned reads of blocksize: $bs"
14039                 # with 'u', multiop randomly unaligns the io from the buffer
14040                 $MULTIOP $DIR/$tfile.1 \
14041                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
14042                         error "multiop memory unaligned read failed, $bs"
14043
14044         done
14045         rm -f $DIR/$tfile*
14046 }
14047 run_test 119h "basic tests of memory unaligned dio"
14048
14049 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14050 test_119i()
14051 {
14052         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14053         which aiocp || skip_env "no aiocp installed"
14054
14055         local stripe_size=$((1024 * 1024)) #1 MiB
14056         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14057         local file_size=$((25 * stripe_size))
14058         local bsizes
14059
14060         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14061         stack_trap "rm -f $DIR/$tfile.*"
14062
14063         # Just a bit bigger than the largest size in the test set below
14064         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14065                 error "buffered i/o to create file failed"
14066
14067         if zfs_or_rotational; then
14068                 # DIO on ZFS can take up to 2 seconds per IO
14069                 # rotational is better, but still slow.
14070                 # Limit testing on those media to larger sizes
14071                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14072                         $((stripe_size + 1024))"
14073         else
14074                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14075                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14076                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14077                         $((stripe_size - 1)) $stripe_size \
14078                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14079                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14080         fi
14081
14082         # Do page aligned and NOT page aligned AIO
14083         for align in 8 512 $((PAGE_SIZE)); do
14084         # Deliberately includes a few aligned sizes
14085         for bs in $bsizes; do
14086                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14087
14088                 echo "bs: $bs, align: $align, file_size $file_size"
14089                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14090                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14091                         error "unaligned aio failed, bs: $bs, align: $align"
14092
14093                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14094                         error "size incorrect"
14095                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14096                         error "files differ"
14097                 rm -f $DIR/$tfile.2
14098         done
14099         done
14100 }
14101 run_test 119i "test unaligned aio at varying sizes"
14102
14103 test_119j()
14104 {
14105         (( $LINUX_VERSION_CODE > $(version_code 4.5.0) )) ||
14106                 skip "needs kernel > 4.5.0 for ki_flags support"
14107
14108         local rpcs
14109         dd if=/dev/urandom of=$DIR/$tfile bs=8 count=1 || error "(0) dd failed"
14110         sync
14111         $LCTL set_param -n osc.*.rpc_stats=0
14112         # Read from page cache, does not generate an rpc
14113         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(1) dd failed"
14114         $LCTL get_param osc.*.rpc_stats
14115         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14116                 sed -n '/pages per rpc/,/^$/p' |
14117                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14118                 END { print reads,writes }'))
14119         [[ ${rpcs[0]} == 0 ]] ||
14120                 error "(3) ${rpcs[0]} != 0 read RPCs"
14121
14122         # Test hybrid IO read
14123         # Force next BIO as DIO
14124         # This forces an RPC to the server
14125         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14126         $LCTL set_param fail_loc=0x1429
14127         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(4) dd failed"
14128         $LCTL get_param osc.*.rpc_stats
14129         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14130                 sed -n '/pages per rpc/,/^$/p' |
14131                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14132                 END { print reads,writes }'))
14133         [[ ${rpcs[0]} == 1 ]] ||
14134                 error "(5) ${rpcs[0]} != 1 read RPCs"
14135
14136         # Test hybrid IO write
14137         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14138         $LCTL set_param fail_loc=0x1429
14139         #NB: We do not check for 0 write RPCs in the BIO case because that
14140         # would make the test racey vs cache flushing
14141         # but the DIO case is guaranteed to generate 1 write RPC
14142         dd if=/dev/zero of=$DIR/$tfile bs=8 count=1 || error "(6) dd failed"
14143         $LCTL get_param osc.*.rpc_stats
14144         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14145                 sed -n '/pages per rpc/,/^$/p' |
14146                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14147                 END { print reads,writes }'))
14148         [[ ${rpcs[1]} == 1 ]] ||
14149                 error "(7) ${rpcs[0]} != 1 read RPCs"
14150 }
14151 run_test 119j "basic tests of hybrid IO switching"
14152
14153 test_119m() {
14154         dio_readv_writev_support
14155
14156         timeout 90s rwv -f $DIR/$tfile -Dw -n 3 0x80000 0x100000 0x180000 ||
14157                 error "DIO aligned writev test failed"
14158         timeout 90s rwv -f $DIR/$tfile -Dr -v -n 2 0x180000 0x100000 ||
14159                 error "DIO aligned readv failed"
14160         rm -f $DIR/$tfile
14161 }
14162 run_test 119m "Test DIO readv/writev: exercise iter duplication"
14163
14164 test_120a() {
14165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14166         remote_mds_nodsh && skip "remote MDS with nodsh"
14167         test_mkdir -i0 -c1 $DIR/$tdir
14168         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14169                 skip_env "no early lock cancel on server"
14170
14171         lru_resize_disable mdc
14172         lru_resize_disable osc
14173         cancel_lru_locks mdc
14174         # asynchronous object destroy at MDT could cause bl ast to client
14175         cancel_lru_locks osc
14176
14177         stat $DIR/$tdir > /dev/null
14178         can1=$(do_facet mds1 \
14179                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14180                awk '/ldlm_cancel/ {print $2}')
14181         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14182                awk '/ldlm_bl_callback/ {print $2}')
14183         test_mkdir -i0 -c1 $DIR/$tdir/d1
14184         can2=$(do_facet mds1 \
14185                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14186                awk '/ldlm_cancel/ {print $2}')
14187         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14188                awk '/ldlm_bl_callback/ {print $2}')
14189         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14190         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14191         lru_resize_enable mdc
14192         lru_resize_enable osc
14193 }
14194 run_test 120a "Early Lock Cancel: mkdir test"
14195
14196 test_120b() {
14197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14198         remote_mds_nodsh && skip "remote MDS with nodsh"
14199         test_mkdir $DIR/$tdir
14200         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14201                 skip_env "no early lock cancel on server"
14202
14203         lru_resize_disable mdc
14204         lru_resize_disable osc
14205         cancel_lru_locks mdc
14206         stat $DIR/$tdir > /dev/null
14207         can1=$(do_facet $SINGLEMDS \
14208                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14209                awk '/ldlm_cancel/ {print $2}')
14210         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14211                awk '/ldlm_bl_callback/ {print $2}')
14212         touch $DIR/$tdir/f1
14213         can2=$(do_facet $SINGLEMDS \
14214                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14215                awk '/ldlm_cancel/ {print $2}')
14216         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14217                awk '/ldlm_bl_callback/ {print $2}')
14218         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14219         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14220         lru_resize_enable mdc
14221         lru_resize_enable osc
14222 }
14223 run_test 120b "Early Lock Cancel: create test"
14224
14225 test_120c() {
14226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14227         remote_mds_nodsh && skip "remote MDS with nodsh"
14228         test_mkdir -i0 -c1 $DIR/$tdir
14229         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14230                 skip "no early lock cancel on server"
14231
14232         lru_resize_disable mdc
14233         lru_resize_disable osc
14234         test_mkdir -i0 -c1 $DIR/$tdir/d1
14235         test_mkdir -i0 -c1 $DIR/$tdir/d2
14236         touch $DIR/$tdir/d1/f1
14237         cancel_lru_locks mdc
14238         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14239         can1=$(do_facet mds1 \
14240                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14241                awk '/ldlm_cancel/ {print $2}')
14242         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14243                awk '/ldlm_bl_callback/ {print $2}')
14244         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14245         can2=$(do_facet mds1 \
14246                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14247                awk '/ldlm_cancel/ {print $2}')
14248         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14249                awk '/ldlm_bl_callback/ {print $2}')
14250         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14251         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14252         lru_resize_enable mdc
14253         lru_resize_enable osc
14254 }
14255 run_test 120c "Early Lock Cancel: link test"
14256
14257 test_120d() {
14258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14259         remote_mds_nodsh && skip "remote MDS with nodsh"
14260         test_mkdir -i0 -c1 $DIR/$tdir
14261         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14262                 skip_env "no early lock cancel on server"
14263
14264         lru_resize_disable mdc
14265         lru_resize_disable osc
14266         touch $DIR/$tdir
14267         cancel_lru_locks mdc
14268         stat $DIR/$tdir > /dev/null
14269         can1=$(do_facet mds1 \
14270                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14271                awk '/ldlm_cancel/ {print $2}')
14272         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14273                awk '/ldlm_bl_callback/ {print $2}')
14274         chmod a+x $DIR/$tdir
14275         can2=$(do_facet mds1 \
14276                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14277                awk '/ldlm_cancel/ {print $2}')
14278         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14279                awk '/ldlm_bl_callback/ {print $2}')
14280         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14281         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14282         lru_resize_enable mdc
14283         lru_resize_enable osc
14284 }
14285 run_test 120d "Early Lock Cancel: setattr test"
14286
14287 test_120e() {
14288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14289         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14290                 skip_env "no early lock cancel on server"
14291         remote_mds_nodsh && skip "remote MDS with nodsh"
14292
14293         local dlmtrace_set=false
14294
14295         test_mkdir -i0 -c1 $DIR/$tdir
14296         lru_resize_disable mdc
14297         lru_resize_disable osc
14298         ! $LCTL get_param debug | grep -q dlmtrace &&
14299                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14300         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14301         cancel_lru_locks mdc
14302         cancel_lru_locks osc
14303         dd if=$DIR/$tdir/f1 of=/dev/null
14304         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14305         # XXX client can not do early lock cancel of OST lock
14306         # during unlink (LU-4206), so cancel osc lock now.
14307         sleep 2
14308         cancel_lru_locks osc
14309         can1=$(do_facet mds1 \
14310                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14311                awk '/ldlm_cancel/ {print $2}')
14312         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14313                awk '/ldlm_bl_callback/ {print $2}')
14314         unlink $DIR/$tdir/f1
14315         sleep 5
14316         can2=$(do_facet mds1 \
14317                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14318                awk '/ldlm_cancel/ {print $2}')
14319         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14320                awk '/ldlm_bl_callback/ {print $2}')
14321         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14322                 $LCTL dk $TMP/cancel.debug.txt
14323         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14324                 $LCTL dk $TMP/blocking.debug.txt
14325         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14326         lru_resize_enable mdc
14327         lru_resize_enable osc
14328 }
14329 run_test 120e "Early Lock Cancel: unlink test"
14330
14331 test_120f() {
14332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14333         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14334                 skip_env "no early lock cancel on server"
14335         remote_mds_nodsh && skip "remote MDS with nodsh"
14336
14337         test_mkdir -i0 -c1 $DIR/$tdir
14338         lru_resize_disable mdc
14339         lru_resize_disable osc
14340         test_mkdir -i0 -c1 $DIR/$tdir/d1
14341         test_mkdir -i0 -c1 $DIR/$tdir/d2
14342         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14343         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14344         cancel_lru_locks mdc
14345         cancel_lru_locks osc
14346         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14347         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14348         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14349         # XXX client can not do early lock cancel of OST lock
14350         # during rename (LU-4206), so cancel osc lock now.
14351         sleep 2
14352         cancel_lru_locks osc
14353         can1=$(do_facet mds1 \
14354                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14355                awk '/ldlm_cancel/ {print $2}')
14356         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14357                awk '/ldlm_bl_callback/ {print $2}')
14358         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14359         sleep 5
14360         can2=$(do_facet mds1 \
14361                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14362                awk '/ldlm_cancel/ {print $2}')
14363         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14364                awk '/ldlm_bl_callback/ {print $2}')
14365         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14366         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14367         lru_resize_enable mdc
14368         lru_resize_enable osc
14369 }
14370 run_test 120f "Early Lock Cancel: rename test"
14371
14372 test_120g() {
14373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14374         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14375                 skip_env "no early lock cancel on server"
14376         remote_mds_nodsh && skip "remote MDS with nodsh"
14377
14378         lru_resize_disable mdc
14379         lru_resize_disable osc
14380         count=10000
14381         echo create $count files
14382         test_mkdir $DIR/$tdir
14383         cancel_lru_locks mdc
14384         cancel_lru_locks osc
14385         t0=$(date +%s)
14386
14387         can0=$(do_facet $SINGLEMDS \
14388                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14389                awk '/ldlm_cancel/ {print $2}')
14390         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14391                awk '/ldlm_bl_callback/ {print $2}')
14392         createmany -o $DIR/$tdir/f $count
14393         sync
14394         can1=$(do_facet $SINGLEMDS \
14395                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14396                awk '/ldlm_cancel/ {print $2}')
14397         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14398                awk '/ldlm_bl_callback/ {print $2}')
14399         t1=$(date +%s)
14400         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14401         echo rm $count files
14402         rm -r $DIR/$tdir
14403         sync
14404         can2=$(do_facet $SINGLEMDS \
14405                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14406                awk '/ldlm_cancel/ {print $2}')
14407         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14408                awk '/ldlm_bl_callback/ {print $2}')
14409         t2=$(date +%s)
14410         echo total: $count removes in $((t2-t1))
14411         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14412         sleep 2
14413         # wait for commitment of removal
14414         lru_resize_enable mdc
14415         lru_resize_enable osc
14416 }
14417 run_test 120g "Early Lock Cancel: performance test"
14418
14419 test_121() { #bug #10589
14420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14421
14422         rm -rf $DIR/$tfile
14423         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14424 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14425         lctl set_param fail_loc=0x310
14426         cancel_lru_locks osc > /dev/null
14427         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14428         lctl set_param fail_loc=0
14429         [[ $reads -eq $writes ]] ||
14430                 error "read $reads blocks, must be $writes blocks"
14431 }
14432 run_test 121 "read cancel race ========="
14433
14434 test_123a_base() { # was test 123, statahead(bug 11401)
14435         local lsx="$1"
14436
14437         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14438
14439         SLOWOK=0
14440         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14441                 log "testing UP system. Performance may be lower than expected."
14442                 SLOWOK=1
14443         fi
14444         running_in_vm && SLOWOK=1
14445
14446         $LCTL set_param mdc.*.batch_stats=0
14447
14448         rm -rf $DIR/$tdir
14449         test_mkdir $DIR/$tdir
14450         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14451         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14452         MULT=10
14453         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14454                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14455
14456                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14457                 lctl set_param -n llite.*.statahead_max 0
14458                 lctl get_param llite.*.statahead_max
14459                 cancel_lru_locks mdc
14460                 cancel_lru_locks osc
14461                 stime=$(date +%s)
14462                 time $lsx $DIR/$tdir | wc -l
14463                 etime=$(date +%s)
14464                 delta=$((etime - stime))
14465                 log "$lsx $i files without statahead: $delta sec"
14466                 lctl set_param llite.*.statahead_max=$max
14467
14468                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14469                          awk '/statahead.wrong:/ { print $NF }')
14470                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14471                 cancel_lru_locks mdc
14472                 cancel_lru_locks osc
14473                 stime=$(date +%s)
14474                 time $lsx $DIR/$tdir | wc -l
14475                 etime=$(date +%s)
14476                 delta_sa=$((etime - stime))
14477                 log "$lsx $i files with statahead: $delta_sa sec"
14478                 lctl get_param -n llite.*.statahead_stats
14479                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14480                          awk '/statahead.wrong:/ { print $NF }')
14481
14482                 [[ $swrong -lt $ewrong ]] &&
14483                         log "statahead was stopped, maybe too many locks held!"
14484                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14485
14486                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14487                         max=$(lctl get_param -n llite.*.statahead_max |
14488                                 head -n 1)
14489                         lctl set_param -n llite.*.statahead_max 0
14490                         lctl get_param llite.*.statahead_max
14491                         cancel_lru_locks mdc
14492                         cancel_lru_locks osc
14493                         stime=$(date +%s)
14494                         time $lsx $DIR/$tdir | wc -l
14495                         etime=$(date +%s)
14496                         delta=$((etime - stime))
14497                         log "$lsx $i files again without statahead: $delta sec"
14498                         lctl set_param llite.*.statahead_max=$max
14499                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14500                                 if [ $SLOWOK -eq 0 ]; then
14501                                         error "$lsx $i files is slower with statahead!"
14502                                 else
14503                                         log "$lsx $i files is slower with statahead!"
14504                                 fi
14505                                 break
14506                         fi
14507                 fi
14508
14509                 [ $delta -gt 20 ] && break
14510                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14511                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14512         done
14513         log "$lsx done"
14514
14515         stime=$(date +%s)
14516         rm -r $DIR/$tdir
14517         sync
14518         etime=$(date +%s)
14519         delta=$((etime - stime))
14520         log "rm -r $DIR/$tdir/: $delta seconds"
14521         log "rm done"
14522         lctl get_param -n llite.*.statahead_stats
14523         $LCTL get_param mdc.*.batch_stats
14524 }
14525
14526 test_123aa() {
14527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14528
14529         test_123a_base "ls -l"
14530 }
14531 run_test 123aa "verify statahead work"
14532
14533 test_123ab() {
14534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14535
14536         statx_supported || skip_env "Test must be statx() syscall supported"
14537
14538         test_123a_base "$STATX -l"
14539 }
14540 run_test 123ab "verify statahead work by using statx"
14541
14542 test_123ac() {
14543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14544
14545         statx_supported || skip_env "Test must be statx() syscall supported"
14546
14547         local rpcs_before
14548         local rpcs_after
14549         local agl_before
14550         local agl_after
14551
14552         cancel_lru_locks $OSC
14553         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14554         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14555                      awk '/agl.total:/ { print $NF }')
14556         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14557         test_123a_base "$STATX --cached=always -D"
14558         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14559                     awk '/agl.total:/ { print $NF }')
14560         [ $agl_before -eq $agl_after ] ||
14561                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14562         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14563         [ $rpcs_after -eq $rpcs_before ] ||
14564                 error "$STATX should not send glimpse RPCs to $OSC"
14565 }
14566 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14567
14568 test_batch_statahead() {
14569         local max=$1
14570         local batch_max=$2
14571         local num=10000
14572         local batch_rpcs
14573         local unbatch_rpcs
14574         local hit_total
14575
14576         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14577         $LCTL set_param mdc.*.batch_stats=0
14578         $LCTL set_param llite.*.statahead_max=$max
14579         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14580         # Verify that batched statahead is faster than one without statahead
14581         test_123a_base "ls -l"
14582
14583         stack_trap "rm -rf $DIR/$tdir" EXIT
14584         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14585         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14586
14587         # unbatched statahead
14588         $LCTL set_param llite.*.statahead_batch_max=0
14589         $LCTL set_param llite.*.statahead_stats=clear
14590         $LCTL set_param mdc.*.stats=clear
14591         cancel_lru_locks mdc
14592         cancel_lru_locks osc
14593         time ls -l $DIR/$tdir | wc -l
14594         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14595         wait_update_facet client "pgrep ll_sa" "" 35 ||
14596                 error "ll_sa thread is still running"
14597         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14598                     awk '/hit.total:/ { print $NF }')
14599         # hit ratio should be larger than 75% (7500).
14600         (( $hit_total > 7500 )) ||
14601                 error "unbatched statahead hit count ($hit_total) is too low"
14602
14603         # batched statahead
14604         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14605         $LCTL set_param llite.*.statahead_stats=clear
14606         $LCTL set_param mdc.*.batch_stats=clear
14607         $LCTL set_param mdc.*.stats=clear
14608         cancel_lru_locks mdc
14609         cancel_lru_locks osc
14610         time ls -l $DIR/$tdir | wc -l
14611         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14612         # wait for statahead thread to quit and update statahead stats
14613         wait_update_facet client "pgrep ll_sa" "" 35 ||
14614                 error "ll_sa thread is still running"
14615         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14616                     awk '/hit.total:/ { print $NF }')
14617         # hit ratio should be larger than 75% (7500).
14618         (( $hit_total > 7500 )) ||
14619                 error "batched statahead hit count ($hit_total) is too low"
14620
14621         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14622         (( $unbatch_rpcs > $batch_rpcs )) ||
14623                 error "batched statahead does not reduce RPC count"
14624         $LCTL get_param mdc.*.batch_stats
14625 }
14626
14627 test_123ad() {
14628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14629
14630         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14631                 skip "Need server version at least 2.15.53"
14632
14633         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14634                 skip "Server does not support batch RPC"
14635
14636         local max
14637         local batch_max
14638
14639         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14640         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14641
14642         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14643         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14644
14645         test_batch_statahead 32 32
14646         test_batch_statahead 2048 256
14647 }
14648 run_test 123ad "Verify batching statahead works correctly"
14649
14650 test_123b () { # statahead(bug 15027)
14651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14652
14653         test_mkdir $DIR/$tdir
14654         createmany -o $DIR/$tdir/$tfile-%d 1000
14655
14656         cancel_lru_locks mdc
14657         cancel_lru_locks osc
14658
14659 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14660         lctl set_param fail_loc=0x80000803
14661         ls -lR $DIR/$tdir > /dev/null
14662         log "ls done"
14663         lctl set_param fail_loc=0x0
14664         lctl get_param -n llite.*.statahead_stats
14665         rm -r $DIR/$tdir
14666         sync
14667
14668 }
14669 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14670
14671 test_123c() {
14672         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14673
14674         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14675         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14676         touch $DIR/$tdir.1/{1..3}
14677         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14678
14679         remount_client $MOUNT
14680
14681         $MULTIOP $DIR/$tdir.0 Q
14682
14683         # let statahead to complete
14684         ls -l $DIR/$tdir.0 > /dev/null
14685
14686         testid=$(echo $TESTNAME | tr '_' ' ')
14687         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14688                 error "statahead warning" || true
14689 }
14690 run_test 123c "Can not initialize inode warning on DNE statahead"
14691
14692 test_123d() {
14693         local num=100
14694         local swrong
14695         local ewrong
14696
14697         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14698         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14699                 error "setdirstripe $DIR/$tdir failed"
14700         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14701         remount_client $MOUNT
14702         $LCTL get_param llite.*.statahead_max
14703         $LCTL set_param llite.*.statahead_stats=0 ||
14704                 error "clear statahead_stats failed"
14705         swrong=$(lctl get_param -n llite.*.statahead_stats |
14706                  awk '/statahead.wrong:/ { print $NF }')
14707         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14708         # wait for statahead thread finished to update hit/miss stats.
14709         sleep 1
14710         $LCTL get_param -n llite.*.statahead_stats
14711         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14712                  awk '/statahead.wrong:/ { print $NF }')
14713         (( $swrong == $ewrong )) ||
14714                 log "statahead was stopped, maybe too many locks held!"
14715 }
14716 run_test 123d "Statahead on striped directories works correctly"
14717
14718 test_123e() {
14719         local max
14720         local batch_max
14721         local dir=$DIR/$tdir
14722
14723         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14724                 skip "Server does not support batch RPC"
14725
14726         mkdir $dir || error "mkdir $dir failed"
14727         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14728         stack_trap "rm -rf $dir"
14729
14730         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14731
14732         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14733         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14734         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14735         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14736
14737         $LCTL set_param llite.*.statahead_max=2048
14738         $LCTL set_param llite.*.statahead_batch_max=1024
14739
14740         ls -l $dir
14741         $LCTL get_param mdc.*.batch_stats
14742         $LCTL get_param llite.*.statahead_*
14743 }
14744 run_test 123e "statahead with large wide striping"
14745
14746 test_123f() {
14747         local max
14748         local batch_max
14749         local dir=$DIR/$tdir
14750
14751         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14752                 skip "Server does not support batch RPC"
14753
14754         mkdir $dir || error "mkdir $dir failed"
14755         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14756         stack_trap "rm -rf $dir"
14757
14758         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14759
14760         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14761         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14762
14763         $LCTL set_param llite.*.statahead_max=64
14764         $LCTL set_param llite.*.statahead_batch_max=64
14765
14766         ls -l $dir
14767         lctl get_param mdc.*.batch_stats
14768         lctl get_param llite.*.statahead_*
14769
14770         $LCTL set_param llite.*.statahead_max=$max
14771         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14772 }
14773 run_test 123f "Retry mechanism with large wide striping files"
14774
14775 test_123g() {
14776         local dir=$DIR/$tdir
14777         local num=1000
14778
14779         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14780                 skip "Server does not support batch RPC"
14781
14782         mkdir $dir || error "failed to mkdir $dir"
14783         createmany -o $dir/$tfile $num || error "failed creatmany files"
14784         cancel_lru_locks mdc
14785         cancel_lru_locks osc
14786
14787         $LCTL set_param llite.*.statahead_stats=clear
14788         $LCTL set_param mdc.*.batch_stats=clear
14789         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14790                 error "aheadmany $dir with $tfile failed"
14791         wait_update_facet client "pgrep ll_sa" "" 35 ||
14792                 error "ll_sa thread is still running"
14793         $LCTL get_param -n llite.*.statahead_stats
14794         $LCTL get_param -n mdc.*.batch_stats
14795
14796         local count
14797
14798         count=$($LCTL get_param -n llite.*.statahead_stats |
14799                 awk '/hit.total:/ {print $2}')
14800         echo "Hit total: $count"
14801         # Hit ratio should be >= 75%
14802         (( $count > num * 75 / 100 )) ||
14803                 error "hit total $count is be > 75% of $num"
14804 }
14805 run_test 123g "Test for stat-ahead advise"
14806
14807 test_123h_base() {
14808         local dir=$DIR/$tdir
14809         local cmd="touch $dir/$tfile.{$1}"
14810         local fcnt=$2
14811
14812         stack_trap "rm -rf $dir"
14813         mkdir -p $dir || error "failed to mkdir $dir"
14814         eval $cmd
14815
14816         cancel_lru_locks mdc
14817         $LCTL set_param llite.*.statahead_stats=clear
14818         $LCTL set_param mdc.*.batch_stats=0
14819         $LCTL set_param llite.*.statahead_max=1024
14820         $LCTL set_param llite.*.statahead_batch_max=1024
14821         lctl get_param -n llite.*.statahead_stats
14822         du -a $dir > /dev/null
14823         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14824         wait_update_facet client "pgrep ll_sa" "" 35 ||
14825                 error "ll_sa statahead thread does not quit in 35s"
14826         $LCTL get_param -n llite.*.statahead_stats
14827         $LCTL get_param -n mdc.*.batch_stats
14828
14829         local count=$($LCTL get_param -n llite.*.statahead_stats |
14830                         awk '/fname.total:/ {print $2}')
14831
14832         [ $count == 1 ] || error "File name pattern statahead not trigger"
14833         count=$($LCTL get_param -n llite.*.statahead_stats |
14834                 awk '/hit.total:/ {print $2}')
14835         # Hit ratio should be >= 75%
14836         (( $count > fcnt * 75 / 100 )) ||
14837                 error "hit total is too low: $count"
14838         rm -rf $dir || error "rm -rf $dir failed"
14839 }
14840
14841 test_123h() {
14842         local max
14843         local batch_max
14844         local enabled
14845
14846         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14847                 skip "Server does not support batch RPC"
14848
14849         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14850         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14851         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14852         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14853         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14854         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14855
14856         $LCTL set_param llite.*.enable_statahead_fname=1
14857
14858         echo "Scan a directory with number regularized fname"
14859         test_123h_base "0..10000" 10000
14860
14861         echo "Scan a directory with zeroed padding number regularized fname"
14862         test_123h_base "000000..010000" 10000
14863 }
14864 run_test 123h "Verify statahead work with the fname pattern via du"
14865
14866 test_123i_base() {
14867         local fmt=$1
14868         local iocmd=$2
14869         local dir=$DIR/$tdir
14870         local cmd="createmany -m $fmt"
14871
14872         echo "Command:"
14873         echo "- $cmd"
14874         echo "- $iocmd"
14875         stack_trap "unlinkmany $fmt"
14876         mkdir -p $dir || error "failed to mkdir $dir"
14877         eval $cmd
14878
14879         cancel_lru_locks mdc
14880         $LCTL set_param llite.*.statahead_stats=clear
14881         $LCTL set_param mdc.*.batch_stats=0
14882
14883         echo "statahead_stats (Pre):"
14884         $LCTL get_param -n llite.*.statahead_stats
14885         eval $iocmd || error "$iocmd failed"
14886         echo "statahead_stats (Post):"
14887         $LCTL get_param -n llite.*.statahead_stats
14888         $LCTL get_param -n mdc.*.batch_stats
14889
14890         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14891         wait_update_facet client "pgrep ll_sa" "" 35 ||
14892                 error "ll_sa statahead thread does not quit in 35s"
14893         $LCTL get_param -n llite.*.statahead_stats
14894         $LCTL get_param -n mdc.*.batch_stats
14895
14896         local count=$($LCTL get_param -n llite.*.statahead_stats |
14897                         awk '/fname.total:/ {print $2}')
14898
14899         [ $count == 1 ] || error "File name pattern statahead not trigger"
14900         count=$($LCTL get_param -n llite.*.statahead_stats |
14901                 awk '/hit.total:/ {print $2}')
14902         # Hit ratio should be >= 75%
14903         (( $count > 750 )) || error "hit total is too low: $count"
14904 }
14905
14906 test_123i() {
14907         local dir=$DIR/$tdir
14908         local cnt=1000
14909         local max
14910         local batch_max
14911         local enabled
14912         local min
14913
14914         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14915                 skip "Server does not support batch RPC"
14916
14917         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14918         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14919         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14920         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14921         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14922         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14923         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14924         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14925         $LCTL set_param llite.*.statahead_max=1024
14926         $LCTL set_param llite.*.statahead_batch_max=32
14927         $LCTL set_param llite.*.statahead_min=64
14928         $LCTL set_param llite.*.enable_statahead_fname=1
14929
14930         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14931         test_123i_base "$dir/$tfile $cnt" \
14932                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14933 }
14934 run_test 123i "Verify statahead work with the fname indexing pattern"
14935
14936 test_123j() {
14937         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
14938
14939         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14940                 skip "Server does not support batch RPC"
14941
14942         local enabled
14943
14944         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14945         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14946         $LCTL set_param llite.*.enable_statahead_fname=1
14947
14948         stack_trap "rm -rf $DIR/${tdir}.{1..11}"
14949
14950         mkdir $DIR/${tdir}.{1..10} ||
14951                 error "failed to mkdir $DIR/${tdir}.{1..10}"
14952         cancel_lru_locks mdc
14953
14954         for i in $(seq 1 10); do
14955                 stat $DIR/${tdir}.$i || error "failed to stat $DIR/${tdir}.$i"
14956         done
14957
14958         stat $DIR/${tdir}.11
14959         $LFS mkdir -i $((MDSCOUNT - 1)) -c 2 -H all_char $DIR/${tdir}.11 ||
14960                 error "failed to mkdir $DIR/${tdir}.11"
14961         touch $DIR/${tdir}.11/$tfile ||
14962                 error "failed to create file $DIR/${tdir}.11/$tfile"
14963 }
14964 run_test 123j "-ENOENT error from batched statahead be handled correctly"
14965
14966 test_123k() {
14967         MDTEST=${MDTEST:=$(which mdtest 2> /dev/null || true)}
14968         [[ -n "$MDTEST" ]] || skip_env "mdtest not found"
14969
14970         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14971                 skip "Server does not support batch RPC"
14972
14973         local enabled
14974
14975         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14976         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14977         $LCTL set_param llite.*.enable_statahead_fname=1
14978
14979         local np=2
14980
14981         mpi_run -np $np $MDTEST -C -F -n 1000 -d $DIR/$tdir
14982         cancel_lru_locks mdc
14983         $LCTL set_param llite.*.statahead_stats=clear
14984         $LCTL set_param mdc.*.batch_stats=0
14985         mpi_run -np $np $MDTEST -T -F -n 1000 -d $DIR/$tdir
14986         #umount_client $MOUNT || error "failed to umount client"
14987         echo "Sleep to wait statahead thread (ll_sa_xxx) to exit ..."
14988         wait_update_facet client "pgrep ll_sa" "" 35 ||
14989                 error "ll_sa thread is still running"
14990
14991         $LCTL get_param -n llite.*.statahead_stats
14992         $LCTL get_param -n mdc.*.batch_stats
14993         ps -el | grep ll_sa
14994
14995         local count=$($LCTL get_param -n llite.*.statahead_stats |
14996                         awk '/fname.total:/ {print $2}')
14997
14998         [ $count == $np ] || error "File name pattern statahead not trigger"
14999         count=$($LCTL get_param -n llite.*.statahead_stats |
15000                 awk '/hit.total:/ {print $2}')
15001         # Hit ratio should be >= 75%
15002         [ $count -gt $((np * 1000 * 75 / 100)) ] ||
15003                 error "hit total is too low: $count"
15004 }
15005 run_test 123k "Verify statahead work with mdtest shared stat() mode"
15006
15007 test_123l() {
15008         local dir=$DIR/$tdir
15009         local cmd="touch $dir/$tfile.{000000..000100}"
15010
15011         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
15012                 skip "Server does not support batch RPC"
15013
15014         stack_trap "rm -rf $dir"
15015         mkdir -p $dir || error "failed to mkdir $dir"
15016         eval $cmd
15017
15018         cancel_lru_locks mdc
15019         $LCTL set_param llite.*.statahead_stats=clear
15020         $LCTL set_param mdc.*.batch_stats=0
15021
15022         local max
15023         local batch_max
15024         local enabled
15025
15026         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
15027         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
15028         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
15029         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
15030         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
15031         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
15032         $LCTL set_param llite.*.enable_statahead_fname=1
15033         $LCTL set_param llite.*.statahead_max=1024
15034         $LCTL set_param llite.*.statahead_batch_max=32
15035         $LCTL get_param -n llite.*.statahead_stats
15036         #define OBD_FAIL_LLITE_STATAHEAD_PAUSE  0x1433
15037         $LCTL set_param fail_loc=0x80001433 fail_val=35
15038         ls $dir/* > /dev/null
15039         $LCTL get_param -n llite.*.statahead_stats
15040         $LCTL get_param -n mdc.*.batch_stats
15041
15042         echo "Sleep to wait the statahead thread (ll_sa_xxx) to exit ..."
15043         wait_update_facet client "pgrep ll_sa" "" 35 ||
15044                 error "ll_sa thread is still running"
15045         $LCTL get_param -n llite.*.statahead_stats
15046 }
15047 run_test 123l "Avoid panic when revalidate a local cached entry"
15048
15049 test_124a() {
15050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15051         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15052                 skip_env "no lru resize on server"
15053
15054         local NR=2000
15055
15056         test_mkdir $DIR/$tdir
15057
15058         log "create $NR files at $DIR/$tdir"
15059         createmany -o $DIR/$tdir/f $NR ||
15060                 error "failed to create $NR files in $DIR/$tdir"
15061
15062         cancel_lru_locks mdc
15063         ls -l $DIR/$tdir > /dev/null
15064
15065         local NSDIR=""
15066         local LRU_SIZE=0
15067         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
15068                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
15069                 LRU_SIZE=$($LCTL get_param -n $PARAM)
15070                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
15071                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
15072                         log "NSDIR=$NSDIR"
15073                         log "NS=$(basename $NSDIR)"
15074                         break
15075                 fi
15076         done
15077
15078         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
15079                 skip "Not enough cached locks created!"
15080         fi
15081         log "LRU=$LRU_SIZE"
15082
15083         local SLEEP=30
15084
15085         # We know that lru resize allows one client to hold $LIMIT locks
15086         # for 10h. After that locks begin to be killed by client.
15087         local MAX_HRS=10
15088         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
15089         log "LIMIT=$LIMIT"
15090         if [ $LIMIT -lt $LRU_SIZE ]; then
15091                 skip "Limit is too small $LIMIT"
15092         fi
15093
15094         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
15095         # killing locks. Some time was spent for creating locks. This means
15096         # that up to the moment of sleep finish we must have killed some of
15097         # them (10-100 locks). This depends on how fast ther were created.
15098         # Many of them were touched in almost the same moment and thus will
15099         # be killed in groups.
15100         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
15101
15102         # Use $LRU_SIZE_B here to take into account real number of locks
15103         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
15104         local LRU_SIZE_B=$LRU_SIZE
15105         log "LVF=$LVF"
15106         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
15107         log "OLD_LVF=$OLD_LVF"
15108         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
15109
15110         # Let's make sure that we really have some margin. Client checks
15111         # cached locks every 10 sec.
15112         SLEEP=$((SLEEP+20))
15113         log "Sleep ${SLEEP} sec"
15114         local SEC=0
15115         while ((SEC<$SLEEP)); do
15116                 echo -n "..."
15117                 sleep 5
15118                 SEC=$((SEC+5))
15119                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
15120                 echo -n "$LRU_SIZE"
15121         done
15122         echo ""
15123         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
15124         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
15125
15126         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
15127                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
15128                 unlinkmany $DIR/$tdir/f $NR
15129                 return
15130         }
15131
15132         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
15133         log "unlink $NR files at $DIR/$tdir"
15134         unlinkmany $DIR/$tdir/f $NR
15135 }
15136 run_test 124a "lru resize ======================================="
15137
15138 get_max_pool_limit()
15139 {
15140         local limit=$($LCTL get_param \
15141                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
15142         local max=0
15143         for l in $limit; do
15144                 if [[ $l -gt $max ]]; then
15145                         max=$l
15146                 fi
15147         done
15148         echo $max
15149 }
15150
15151 test_124b() {
15152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15153         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15154                 skip_env "no lru resize on server"
15155
15156         LIMIT=$(get_max_pool_limit)
15157
15158         NR=$(($(default_lru_size)*20))
15159         if [[ $NR -gt $LIMIT ]]; then
15160                 log "Limit lock number by $LIMIT locks"
15161                 NR=$LIMIT
15162         fi
15163
15164         IFree=$(mdsrate_inodes_available)
15165         if [ $IFree -lt $NR ]; then
15166                 log "Limit lock number by $IFree inodes"
15167                 NR=$IFree
15168         fi
15169
15170         lru_resize_disable mdc
15171         test_mkdir -p $DIR/$tdir/disable_lru_resize
15172
15173         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
15174         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
15175         cancel_lru_locks mdc
15176         stime=`date +%s`
15177         PID=""
15178         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15179         PID="$PID $!"
15180         sleep 2
15181         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15182         PID="$PID $!"
15183         sleep 2
15184         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15185         PID="$PID $!"
15186         wait $PID
15187         etime=`date +%s`
15188         nolruresize_delta=$((etime-stime))
15189         log "ls -la time: $nolruresize_delta seconds"
15190         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15191         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
15192
15193         lru_resize_enable mdc
15194         test_mkdir -p $DIR/$tdir/enable_lru_resize
15195
15196         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
15197         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
15198         cancel_lru_locks mdc
15199         stime=`date +%s`
15200         PID=""
15201         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15202         PID="$PID $!"
15203         sleep 2
15204         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15205         PID="$PID $!"
15206         sleep 2
15207         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15208         PID="$PID $!"
15209         wait $PID
15210         etime=`date +%s`
15211         lruresize_delta=$((etime-stime))
15212         log "ls -la time: $lruresize_delta seconds"
15213         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15214
15215         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15216                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15217         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15218                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15219         else
15220                 log "lru resize performs the same with no lru resize"
15221         fi
15222         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15223 }
15224 run_test 124b "lru resize (performance test) ======================="
15225
15226 test_124c() {
15227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15228         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15229                 skip_env "no lru resize on server"
15230
15231         # cache ununsed locks on client
15232         local nr=100
15233         cancel_lru_locks mdc
15234         test_mkdir $DIR/$tdir
15235         createmany -o $DIR/$tdir/f $nr ||
15236                 error "failed to create $nr files in $DIR/$tdir"
15237         ls -l $DIR/$tdir > /dev/null
15238
15239         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15240         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15241         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15242         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15243         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15244
15245         # set lru_max_age to 1 sec
15246         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15247         echo "sleep $((recalc_p * 2)) seconds..."
15248         sleep $((recalc_p * 2))
15249
15250         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15251         # restore lru_max_age
15252         $LCTL set_param -n $nsdir.lru_max_age $max_age
15253         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15254         unlinkmany $DIR/$tdir/f $nr
15255 }
15256 run_test 124c "LRUR cancel very aged locks"
15257
15258 test_124d() {
15259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15260         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15261                 skip_env "no lru resize on server"
15262
15263         # cache ununsed locks on client
15264         local nr=100
15265
15266         lru_resize_disable mdc
15267         stack_trap "lru_resize_enable mdc" EXIT
15268
15269         cancel_lru_locks mdc
15270
15271         # asynchronous object destroy at MDT could cause bl ast to client
15272         test_mkdir $DIR/$tdir
15273         createmany -o $DIR/$tdir/f $nr ||
15274                 error "failed to create $nr files in $DIR/$tdir"
15275         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15276
15277         ls -l $DIR/$tdir > /dev/null
15278
15279         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15280         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15281         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15282         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15283
15284         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15285
15286         # set lru_max_age to 1 sec
15287         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15288         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15289
15290         echo "sleep $((recalc_p * 2)) seconds..."
15291         sleep $((recalc_p * 2))
15292
15293         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15294
15295         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15296 }
15297 run_test 124d "cancel very aged locks if lru-resize disabled"
15298
15299 test_125() { # 13358
15300         $LCTL get_param -n llite.*.client_type | grep -q local ||
15301                 skip "must run as local client"
15302         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15303                 skip_env "must have acl enabled"
15304         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15305         id $USER0 || skip_env "missing user $USER0"
15306
15307         test_mkdir $DIR/$tdir
15308         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15309         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15310                 error "setfacl $DIR/$tdir failed"
15311         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15312 }
15313 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15314
15315 test_126() { # bug 12829/13455
15316         $GSS && skip_env "must run as gss disabled"
15317         $LCTL get_param -n llite.*.client_type | grep -q local ||
15318                 skip "must run as local client"
15319         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15320
15321         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15322         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15323         rm -f $DIR/$tfile
15324         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15325 }
15326 run_test 126 "check that the fsgid provided by the client is taken into account"
15327
15328 test_127a() { # bug 15521
15329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15330         local name count samp unit min max sum sumsq
15331         local tmpfile=$TMP/$tfile.tmp
15332
15333         # enable stats header if it is disabled
15334         $LCTL set_param enable_stats_header=1
15335
15336         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15337         echo "stats before reset"
15338         stack_trap "rm -f $tmpfile"
15339         local now=$(date +%s)
15340
15341         $LCTL get_param osc.*.stats | tee $tmpfile
15342
15343         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15344         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15345         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15346         local uptime=$(awk '{ print $1 }' /proc/uptime)
15347
15348         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15349         (( ${snapshot_time%\.*} >= $now - 5 &&
15350            ${snapshot_time%\.*} <= $now + 5 )) ||
15351                 error "snapshot_time=$snapshot_time != now=$now"
15352         # elapsed _should_ be from mount, but at least less than uptime
15353         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15354                 error "elapsed=$elapsed > uptime=$uptime"
15355         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15356            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15357                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15358
15359         $LCTL set_param osc.*.stats=0
15360         local reset=$(date +%s)
15361         local fsize=$((2048 * 1024))
15362
15363         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15364         cancel_lru_locks osc
15365         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15366
15367         now=$(date +%s)
15368         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15369         while read name count samp unit min max sum sumsq; do
15370                 [[ "$samp" == "samples" ]] || continue
15371
15372                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15373                 [ ! $min ] && error "Missing min value for $name proc entry"
15374                 eval $name=$count || error "Wrong proc format"
15375
15376                 case $name in
15377                 read_bytes|write_bytes)
15378                         [[ "$unit" =~ "bytes" ]] ||
15379                                 error "unit is not 'bytes': $unit"
15380                         (( $min >= 4096 )) || error "min is too small: $min"
15381                         (( $min <= $fsize )) || error "min is too big: $min"
15382                         (( $max >= 4096 )) || error "max is too small: $max"
15383                         (( $max <= $fsize )) || error "max is too big: $max"
15384                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15385                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15386                                 error "sumsquare is too small: $sumsq"
15387                         (( $sumsq <= $fsize * $fsize )) ||
15388                                 error "sumsquare is too big: $sumsq"
15389                         ;;
15390                 ost_read|ost_write)
15391                         [[ "$unit" =~ "usec" ]] ||
15392                                 error "unit is not 'usec': $unit"
15393                         ;;
15394                 *)      ;;
15395                 esac
15396         done < $tmpfile
15397
15398         #check that we actually got some stats
15399         [ "$read_bytes" ] || error "Missing read_bytes stats"
15400         [ "$write_bytes" ] || error "Missing write_bytes stats"
15401         [ "$read_bytes" != 0 ] || error "no read done"
15402         [ "$write_bytes" != 0 ] || error "no write done"
15403
15404         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15405         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15406         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15407
15408         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15409         (( ${snapshot_time%\.*} >= $now - 5 &&
15410            ${snapshot_time%\.*} <= $now + 5 )) ||
15411                 error "reset snapshot_time=$snapshot_time != now=$now"
15412         # elapsed should be from time of stats reset
15413         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15414            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15415                 error "reset elapsed=$elapsed > $now - $reset"
15416         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15417            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15418                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15419 }
15420 run_test 127a "verify the client stats are sane"
15421
15422 test_127b() { # bug LU-333
15423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15424         local name count samp unit min max sum sumsq
15425
15426         echo "stats before reset"
15427         $LCTL get_param llite.*.stats
15428         $LCTL set_param llite.*.stats=0
15429
15430         # perform 2 reads and writes so MAX is different from SUM.
15431         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15432         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15433         cancel_lru_locks osc
15434         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15435         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15436
15437         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15438         stack_trap "rm -f $TMP/$tfile.tmp"
15439         while read name count samp unit min max sum sumsq; do
15440                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15441                 eval $name=$count || error "Wrong proc format"
15442
15443                 case $name in
15444                 read_bytes|write_bytes)
15445                         [[ "$unit" =~ "bytes" ]] ||
15446                                 error "unit is not 'bytes': $unit"
15447                         (( $count == 2 )) || error "count is not 2: $count"
15448                         (( $min == $PAGE_SIZE )) ||
15449                                 error "min is not $PAGE_SIZE: $min"
15450                         (( $max == $PAGE_SIZE )) ||
15451                                 error "max is not $PAGE_SIZE: $max"
15452                         (( $sum == $PAGE_SIZE * 2 )) ||
15453                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15454                         ;;
15455                 read|write)
15456                         [[ "$unit" =~ "usec" ]] ||
15457                                 error "unit is not 'usec': $unit"
15458                         ;;
15459                 *)      ;;
15460                 esac
15461         done < $TMP/$tfile.tmp
15462
15463         #check that we actually got some stats
15464         [ "$read_bytes" ] || error "Missing read_bytes stats"
15465         [ "$write_bytes" ] || error "Missing write_bytes stats"
15466         [ "$read_bytes" != 0 ] || error "no read done"
15467         [ "$write_bytes" != 0 ] || error "no write done"
15468 }
15469 run_test 127b "verify the llite client stats are sane"
15470
15471 test_127c() { # LU-12394
15472         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15473         local size
15474         local bsize
15475         local reads
15476         local writes
15477         local count
15478
15479         $LCTL set_param llite.*.extents_stats=1
15480         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15481
15482         # Use two stripes so there is enough space in default config
15483         $LFS setstripe -c 2 $DIR/$tfile
15484
15485         # Extent stats start at 0-4K and go in power of two buckets
15486         # LL_HIST_START = 12 --> 2^12 = 4K
15487         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15488         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15489         # small configs
15490         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15491                 do
15492                 # Write and read, 2x each, second time at a non-zero offset
15493                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15494                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15495                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15496                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15497                 rm -f $DIR/$tfile
15498         done
15499
15500         $LCTL get_param llite.*.extents_stats
15501
15502         count=2
15503         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15504                 do
15505                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15506                                 grep -m 1 $bsize)
15507                 reads=$(echo $bucket | awk '{print $5}')
15508                 writes=$(echo $bucket | awk '{print $9}')
15509                 [ "$reads" -eq $count ] ||
15510                         error "$reads reads in < $bsize bucket, expect $count"
15511                 [ "$writes" -eq $count ] ||
15512                         error "$writes writes in < $bsize bucket, expect $count"
15513         done
15514
15515         # Test mmap write and read
15516         $LCTL set_param llite.*.extents_stats=c
15517         size=512
15518         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15519         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15520         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15521
15522         $LCTL get_param llite.*.extents_stats
15523
15524         count=$(((size*1024) / PAGE_SIZE))
15525
15526         bsize=$((2 * PAGE_SIZE / 1024))K
15527
15528         bucket=$($LCTL get_param -n llite.*.extents_stats |
15529                         grep -m 1 $bsize)
15530         reads=$(echo $bucket | awk '{print $5}')
15531         writes=$(echo $bucket | awk '{print $9}')
15532         # mmap writes fault in the page first, creating an additonal read
15533         [ "$reads" -eq $((2 * count)) ] ||
15534                 error "$reads reads in < $bsize bucket, expect $count"
15535         [ "$writes" -eq $count ] ||
15536                 error "$writes writes in < $bsize bucket, expect $count"
15537 }
15538 run_test 127c "test llite extent stats with regular & mmap i/o"
15539
15540 test_128() { # bug 15212
15541         touch $DIR/$tfile
15542         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15543                 find $DIR/$tfile
15544                 find $DIR/$tfile
15545         EOF
15546
15547         result=$(grep error $TMP/$tfile.log)
15548         rm -f $DIR/$tfile $TMP/$tfile.log
15549         [ -z "$result" ] ||
15550                 error "consecutive find's under interactive lfs failed"
15551 }
15552 run_test 128 "interactive lfs for 2 consecutive find's"
15553
15554 set_dir_limits () {
15555         local mntdev
15556         local canondev
15557         local node
15558
15559         local ldproc=/proc/fs/ldiskfs
15560         local facets=$(get_facets MDS)
15561
15562         for facet in ${facets//,/ }; do
15563                 canondev=$(ldiskfs_canon \
15564                            *.$(convert_facet2label $facet).mntdev $facet)
15565                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15566                         ldproc=/sys/fs/ldiskfs
15567                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15568                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15569         done
15570 }
15571
15572 check_mds_dmesg() {
15573         local facets=$(get_facets MDS)
15574         for facet in ${facets//,/ }; do
15575                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15576         done
15577         return 1
15578 }
15579
15580 test_129() {
15581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15582         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15583                 skip "Need MDS version with at least 2.5.56"
15584         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15585                 skip_env "ldiskfs only test"
15586         fi
15587         remote_mds_nodsh && skip "remote MDS with nodsh"
15588
15589         local ENOSPC=28
15590         local has_warning=false
15591
15592         rm -rf $DIR/$tdir
15593         mkdir -p $DIR/$tdir
15594
15595         # block size of mds1
15596         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15597         set_dir_limits $maxsize $((maxsize * 6 / 8))
15598         stack_trap "set_dir_limits 0 0"
15599         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15600         local dirsize=$(stat -c%s "$DIR/$tdir")
15601         local nfiles=0
15602         while (( $dirsize <= $maxsize )); do
15603                 $MCREATE $DIR/$tdir/file_base_$nfiles
15604                 rc=$?
15605                 # check two errors:
15606                 # ENOSPC for ext4 max_dir_size, which has been used since
15607                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15608                 if (( rc == ENOSPC )); then
15609                         set_dir_limits 0 0
15610                         echo "rc=$rc returned as expected after $nfiles files"
15611
15612                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15613                                 error "create failed w/o dir size limit"
15614
15615                         # messages may be rate limited if test is run repeatedly
15616                         check_mds_dmesg '"is approaching max"' ||
15617                                 echo "warning message should be output"
15618                         check_mds_dmesg '"has reached max"' ||
15619                                 echo "reached message should be output"
15620
15621                         dirsize=$(stat -c%s "$DIR/$tdir")
15622
15623                         [[ $dirsize -ge $maxsize ]] && return 0
15624                         error "dirsize $dirsize < $maxsize after $nfiles files"
15625                 elif (( rc != 0 )); then
15626                         break
15627                 fi
15628                 nfiles=$((nfiles + 1))
15629                 dirsize=$(stat -c%s "$DIR/$tdir")
15630         done
15631
15632         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15633 }
15634 run_test 129 "test directory size limit ========================"
15635
15636 OLDIFS="$IFS"
15637 cleanup_130() {
15638         trap 0
15639         IFS="$OLDIFS"
15640         rm -f $DIR/$tfile
15641 }
15642
15643 test_130a() {
15644         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15645         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15646
15647         trap cleanup_130 EXIT RETURN
15648
15649         local fm_file=$DIR/$tfile
15650         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15651         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15652                 error "dd failed for $fm_file"
15653
15654         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15655         filefrag -ves $fm_file
15656         local rc=$?
15657         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15658                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15659         (( $rc == 0 )) || error "filefrag $fm_file failed"
15660
15661         filefrag_op=$(filefrag -ve -k $fm_file |
15662                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15663         local lun=$($LFS getstripe -i $fm_file)
15664
15665         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15666         IFS=$'\n'
15667         local tot_len=0
15668         for line in $filefrag_op; do
15669                 local frag_lun=$(echo $line | cut -d: -f5)
15670                 local ext_len=$(echo $line | cut -d: -f4)
15671
15672                 if (( $frag_lun != $lun )); then
15673                         error "FIEMAP on 1-stripe file($fm_file) failed"
15674                         return
15675                 fi
15676                 (( tot_len += ext_len ))
15677         done
15678
15679         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15680                 error "FIEMAP on 1-stripe file($fm_file) failed"
15681                 return
15682         fi
15683
15684         echo "FIEMAP on single striped file succeeded"
15685 }
15686 run_test 130a "FIEMAP (1-stripe file)"
15687
15688 test_130b() {
15689         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15690
15691         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15692         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15693         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15694                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15695
15696         trap cleanup_130 EXIT RETURN
15697
15698         local fm_file=$DIR/$tfile
15699         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15700                 error "setstripe on $fm_file"
15701
15702         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15703                 error "dd failed on $fm_file"
15704
15705         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15706         filefrag_op=$(filefrag -ve -k $fm_file |
15707                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15708
15709         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15710                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15711
15712         IFS=$'\n'
15713         local tot_len=0
15714         local num_luns=1
15715
15716         for line in $filefrag_op; do
15717                 local frag_lun=$(echo $line | cut -d: -f5 |
15718                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15719                 local ext_len=$(echo $line | cut -d: -f4)
15720                 if (( $frag_lun != $last_lun )); then
15721                         if (( tot_len != 1024 )); then
15722                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15723                                 return
15724                         else
15725                                 (( num_luns += 1 ))
15726                                 tot_len=0
15727                         fi
15728                 fi
15729                 (( tot_len += ext_len ))
15730                 last_lun=$frag_lun
15731         done
15732         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15733                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15734                 return
15735         fi
15736
15737         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15738 }
15739 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15740
15741 test_130c() {
15742         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15743
15744         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15745         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15746         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15747                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15748
15749         trap cleanup_130 EXIT RETURN
15750
15751         local fm_file=$DIR/$tfile
15752         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15753
15754         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15755                 error "dd failed on $fm_file"
15756
15757         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15758         filefrag_op=$(filefrag -ve -k $fm_file |
15759                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15760
15761         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15762                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15763
15764         IFS=$'\n'
15765         local tot_len=0
15766         local num_luns=1
15767         for line in $filefrag_op; do
15768                 local frag_lun=$(echo $line | cut -d: -f5 |
15769                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15770                 local ext_len=$(echo $line | cut -d: -f4)
15771                 if (( $frag_lun != $last_lun )); then
15772                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15773                         if (( logical != 512 )); then
15774                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15775                                 return
15776                         fi
15777                         if (( tot_len != 512 )); then
15778                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15779                                 return
15780                         else
15781                                 (( num_luns += 1 ))
15782                                 tot_len=0
15783                         fi
15784                 fi
15785                 (( tot_len += ext_len ))
15786                 last_lun=$frag_lun
15787         done
15788         if (( num_luns != 2 || tot_len != 512 )); then
15789                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15790                 return
15791         fi
15792
15793         echo "FIEMAP on 2-stripe file with hole succeeded"
15794 }
15795 run_test 130c "FIEMAP (2-stripe file with hole)"
15796
15797 test_130d() {
15798         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15799
15800         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15801         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15802         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15803                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15804
15805         trap cleanup_130 EXIT RETURN
15806
15807         local fm_file=$DIR/$tfile
15808         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15809                         error "setstripe on $fm_file"
15810
15811         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15812         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15813                 error "dd failed on $fm_file"
15814
15815         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15816         filefrag_op=$(filefrag -ve -k $fm_file |
15817                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15818
15819         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15820                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15821
15822         IFS=$'\n'
15823         local tot_len=0
15824         local num_luns=1
15825         for line in $filefrag_op; do
15826                 local frag_lun=$(echo $line | cut -d: -f5 |
15827                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15828                 local ext_len=$(echo $line | cut -d: -f4)
15829                 if (( $frag_lun != $last_lun )); then
15830                         if (( tot_len != 1024 )); then
15831                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15832                                 return
15833                         else
15834                                 (( num_luns += 1 ))
15835                                 local tot_len=0
15836                         fi
15837                 fi
15838                 (( tot_len += ext_len ))
15839                 last_lun=$frag_lun
15840         done
15841         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15842                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15843                 return
15844         fi
15845
15846         echo "FIEMAP on N-stripe file succeeded"
15847 }
15848 run_test 130d "FIEMAP (N-stripe file)"
15849
15850 test_130e() {
15851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15852
15853         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15854         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15855         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15856                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15857
15858         trap cleanup_130 EXIT RETURN
15859
15860         local fm_file=$DIR/$tfile
15861         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15862         stack_trap "rm -f $fm_file"
15863
15864         local num_blks=512
15865         local expected_len=$(( (num_blks / 2) * 64 ))
15866         for ((i = 0; i < $num_blks; i++)); do
15867                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15868                         conv=notrunc > /dev/null 2>&1
15869         done
15870
15871         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15872         filefrag_op=$(filefrag -ve -k $fm_file |
15873                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15874
15875         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15876
15877         IFS=$'\n'
15878         local tot_len=0
15879         local num_luns=1
15880         for line in $filefrag_op; do
15881                 local frag_lun=$(echo $line | cut -d: -f5)
15882                 local ext_len=$(echo $line | cut -d: -f4)
15883                 if (( $frag_lun != $last_lun )); then
15884                         if (( tot_len != $expected_len )); then
15885                                 error "OST$last_lun $tot_len != $expected_len"
15886                         else
15887                                 (( num_luns += 1 ))
15888                                 tot_len=0
15889                         fi
15890                 fi
15891                 (( tot_len += ext_len ))
15892                 last_lun=$frag_lun
15893         done
15894         if (( num_luns != 2 || tot_len != $expected_len )); then
15895                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15896         fi
15897
15898         echo "FIEMAP with continuation calls succeeded"
15899 }
15900 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15901
15902 test_130f() {
15903         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15904         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15905         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15906                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15907
15908         local fm_file=$DIR/$tfile
15909         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15910                 error "multiop create with lov_delay_create on $fm_file"
15911
15912         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15913         filefrag_extents=$(filefrag -vek $fm_file |
15914                            awk '/extents? found/ { print $2 }')
15915         if (( $filefrag_extents != 0 )); then
15916                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15917         fi
15918
15919         rm -f $fm_file
15920 }
15921 run_test 130f "FIEMAP (unstriped file)"
15922
15923 test_130g() {
15924         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15925                 skip "Need MDS version with at least 2.12.53 for overstriping"
15926         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15927         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15928         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15929                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15930
15931         local file=$DIR/$tfile
15932         local nr=$((OSTCOUNT * 100))
15933
15934         $LFS setstripe -C $nr -S1M $file ||
15935                 error "failed to setstripe -C $nr $file"
15936
15937         stack_trap "rm -f $file"
15938         dd if=/dev/zero of=$file count=$nr bs=1M
15939         sync
15940         nr=$($LFS getstripe -c $file)
15941
15942         local extents=$(filefrag -v $file |
15943                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15944
15945         echo "filefrag list $extents extents in file with stripecount $nr"
15946         if (( extents < nr )); then
15947                 $LFS getstripe $file
15948                 filefrag -v $file
15949                 error "filefrag printed $extents < $nr extents"
15950         fi
15951 }
15952 run_test 130g "FIEMAP (overstripe file)"
15953
15954 # Test for writev/readv
15955 test_131a() {
15956         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15957                 error "writev test failed"
15958         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15959                 error "readv failed"
15960         rm -f $DIR/$tfile
15961 }
15962 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15963
15964 test_131b() {
15965         local fsize=$((524288 + 1048576 + 1572864))
15966         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15967                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15968                         error "append writev test failed"
15969
15970         ((fsize += 1572864 + 1048576))
15971         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15972                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15973                         error "append writev test failed"
15974         rm -f $DIR/$tfile
15975 }
15976 run_test 131b "test append writev"
15977
15978 test_131c() {
15979         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15980         error "NOT PASS"
15981 }
15982 run_test 131c "test read/write on file w/o objects"
15983
15984 test_131d() {
15985         rwv -f $DIR/$tfile -w -n 1 1572864
15986         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15987         if [ "$NOB" != 1572864 ]; then
15988                 error "Short read filed: read $NOB bytes instead of 1572864"
15989         fi
15990         rm -f $DIR/$tfile
15991 }
15992 run_test 131d "test short read"
15993
15994 test_131e() {
15995         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15996         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15997         error "read hitting hole failed"
15998         rm -f $DIR/$tfile
15999 }
16000 run_test 131e "test read hitting hole"
16001
16002 check_stats() {
16003         local facet=$1
16004         local op=$2
16005         local want=${3:-0}
16006         local res
16007
16008         # open             11 samples [usecs] 468 4793 13658 35791898
16009         case $facet in
16010         mds*) res=($(do_facet $facet \
16011                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
16012                  ;;
16013         ost*) res=($(do_facet $facet \
16014                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
16015                  ;;
16016         *) error "Wrong facet '$facet'" ;;
16017         esac
16018         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
16019         # if $want is zero, it means any stat increment is ok.
16020         if (( $want > 0 )); then
16021                 local count=${res[1]}
16022
16023                 if (( $count != $want )); then
16024                         if [[ $facet =~ "mds" ]]; then
16025                                 do_nodes $(comma_list $(mdts_nodes)) \
16026                                         $LCTL get_param mdt.*.md_stats
16027                         else
16028                                 do_nodes $(comma_list $(osts-nodes)) \
16029                                         $LCTL get_param obdfilter.*.stats
16030                         fi
16031                         error "The $op counter on $facet is $count, not $want"
16032                 fi
16033         fi
16034 }
16035
16036 test_133a() {
16037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16038         remote_ost_nodsh && skip "remote OST with nodsh"
16039         remote_mds_nodsh && skip "remote MDS with nodsh"
16040         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16041                 skip_env "MDS doesn't support rename stats"
16042
16043         local testdir=$DIR/${tdir}/stats_testdir
16044
16045         mkdir_on_mdt0 $DIR/${tdir}
16046
16047         # clear stats.
16048         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16049         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16050
16051         # verify mdt stats first.
16052         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
16053         check_stats $SINGLEMDS "mkdir" 1
16054
16055         # clear "open" from "lfs mkdir" above
16056         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16057         touch ${testdir}/${tfile} || error "touch failed"
16058         check_stats $SINGLEMDS "open" 1
16059         check_stats $SINGLEMDS "close" 1
16060         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
16061                 # open should match close
16062                 ls -lR ${testdir}
16063                 check_stats $SINGLEMDS "open" 2
16064                 check_stats $SINGLEMDS "close" 2
16065         }
16066         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
16067                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
16068                 check_stats $SINGLEMDS "mknod" 2
16069         }
16070         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
16071         check_stats $SINGLEMDS "unlink" 1
16072         rm -f ${testdir}/${tfile} || error "file remove failed"
16073         check_stats $SINGLEMDS "unlink" 2
16074
16075         # remove working dir and check mdt stats again.
16076         rmdir ${testdir} || error "rmdir failed"
16077         check_stats $SINGLEMDS "rmdir" 1
16078
16079         local testdir1=$DIR/${tdir}/stats_testdir1
16080         mkdir_on_mdt0 ${testdir}
16081         mkdir_on_mdt0 ${testdir1}
16082         touch ${testdir1}/test1
16083         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
16084         check_stats $SINGLEMDS "crossdir_rename" 1
16085
16086         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
16087         check_stats $SINGLEMDS "samedir_rename" 1
16088
16089         rm -rf $DIR/${tdir}
16090 }
16091 run_test 133a "Verifying MDT stats ========================================"
16092
16093 test_133b() {
16094         local res
16095
16096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16097         remote_ost_nodsh && skip "remote OST with nodsh"
16098         remote_mds_nodsh && skip "remote MDS with nodsh"
16099
16100         local testdir=$DIR/${tdir}/stats_testdir
16101
16102         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16103         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
16104         touch ${testdir}/${tfile} || error "touch failed"
16105         cancel_lru_locks mdc
16106
16107         # clear stats.
16108         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16109         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16110
16111         # extra mdt stats verification.
16112         chmod 444 ${testdir}/${tfile} || error "chmod failed"
16113         check_stats $SINGLEMDS "setattr" 1
16114         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16115         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
16116         then            # LU-1740
16117                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
16118                 check_stats $SINGLEMDS "getattr" 1
16119         fi
16120         rm -rf $DIR/${tdir}
16121
16122         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
16123         # so the check below is not reliable
16124         [ $MDSCOUNT -eq 1 ] || return 0
16125
16126         # Sleep to avoid a cached response.
16127         #define OBD_STATFS_CACHE_SECONDS 1
16128         sleep 2
16129         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16130         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
16131         $LFS df || error "lfs failed"
16132         check_stats $SINGLEMDS "statfs" 1
16133
16134         # check aggregated statfs (LU-10018)
16135         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
16136                 return 0
16137         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
16138                 return 0
16139         sleep 2
16140         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16141         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
16142         df $DIR
16143         check_stats $SINGLEMDS "statfs" 1
16144
16145         # We want to check that the client didn't send OST_STATFS to
16146         # ost1 but the MDT also uses OST_STATFS for precreate. So some
16147         # extra care is needed here.
16148         if remote_mds; then
16149                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
16150                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
16151
16152                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
16153                 [ "$res" ] && error "OST got STATFS"
16154         fi
16155
16156         return 0
16157 }
16158 run_test 133b "Verifying extra MDT stats =================================="
16159
16160 test_133c() {
16161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16162         remote_ost_nodsh && skip "remote OST with nodsh"
16163         remote_mds_nodsh && skip "remote MDS with nodsh"
16164
16165         local testdir=$DIR/$tdir/stats_testdir
16166
16167         test_mkdir -p $testdir
16168
16169         # verify obdfilter stats.
16170         $LFS setstripe -c 1 -i 0 $testdir/$tfile
16171         sync
16172         cancel_lru_locks osc
16173         wait_delete_completed
16174
16175         # clear stats.
16176         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16177         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16178
16179         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
16180                 error "dd failed"
16181         sync
16182         cancel_lru_locks osc
16183         check_stats ost1 "write" 1
16184
16185         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
16186         check_stats ost1 "read" 1
16187
16188         > $testdir/$tfile || error "truncate failed"
16189         check_stats ost1 "punch" 1
16190
16191         rm -f $testdir/$tfile || error "file remove failed"
16192         wait_delete_completed
16193         check_stats ost1 "destroy" 1
16194
16195         rm -rf $DIR/$tdir
16196 }
16197 run_test 133c "Verifying OST stats ========================================"
16198
16199 order_2() {
16200         local value=$1
16201         local orig=$value
16202         local order=1
16203
16204         while [ $value -ge 2 ]; do
16205                 order=$((order*2))
16206                 value=$((value/2))
16207         done
16208
16209         if [ $orig -gt $order ]; then
16210                 order=$((order*2))
16211         fi
16212         echo $order
16213 }
16214
16215 size_in_KMGT() {
16216     local value=$1
16217     local size=('K' 'M' 'G' 'T');
16218     local i=0
16219     local size_string=$value
16220
16221     while [ $value -ge 1024 ]; do
16222         if [ $i -gt 3 ]; then
16223             #T is the biggest unit we get here, if that is bigger,
16224             #just return XXXT
16225             size_string=${value}T
16226             break
16227         fi
16228         value=$((value >> 10))
16229         if [ $value -lt 1024 ]; then
16230             size_string=${value}${size[$i]}
16231             break
16232         fi
16233         i=$((i + 1))
16234     done
16235
16236     echo $size_string
16237 }
16238
16239 get_rename_size() {
16240         local size=$1
16241         local context=${2:-.}
16242         local sample=$(do_facet $SINGLEMDS $LCTL \
16243                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16244                 grep -A1 $context |
16245                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16246         echo $sample
16247 }
16248
16249 test_133d() {
16250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16251         remote_ost_nodsh && skip "remote OST with nodsh"
16252         remote_mds_nodsh && skip "remote MDS with nodsh"
16253         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16254                 skip_env "MDS doesn't support rename stats"
16255
16256         local testdir1=$DIR/${tdir}/stats_testdir1
16257         local testdir2=$DIR/${tdir}/stats_testdir2
16258         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16259
16260         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16261
16262         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16263         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16264
16265         createmany -o $testdir1/test 512 || error "createmany failed"
16266
16267         # check samedir rename size
16268         mv ${testdir1}/test0 ${testdir1}/test_0
16269
16270         local testdir1_size=$(ls -l $DIR/${tdir} |
16271                 awk '/stats_testdir1/ {print $5}')
16272         local testdir2_size=$(ls -l $DIR/${tdir} |
16273                 awk '/stats_testdir2/ {print $5}')
16274
16275         testdir1_size=$(order_2 $testdir1_size)
16276         testdir2_size=$(order_2 $testdir2_size)
16277
16278         testdir1_size=$(size_in_KMGT $testdir1_size)
16279         testdir2_size=$(size_in_KMGT $testdir2_size)
16280
16281         echo "source rename dir size: ${testdir1_size}"
16282         echo "target rename dir size: ${testdir2_size}"
16283
16284         local cmd="do_facet $SINGLEMDS $LCTL "
16285         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16286
16287         eval $cmd || error "$cmd failed"
16288         local samedir=$($cmd | grep 'same_dir')
16289         local same_sample=$(get_rename_size $testdir1_size)
16290         [ -z "$samedir" ] && error "samedir_rename_size count error"
16291         [[ $same_sample -eq 1 ]] ||
16292                 error "samedir_rename_size error $same_sample"
16293         echo "Check same dir rename stats success"
16294
16295         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16296
16297         # check crossdir rename size
16298         mv ${testdir1}/test_0 ${testdir2}/test_0
16299
16300         testdir1_size=$(ls -l $DIR/${tdir} |
16301                 awk '/stats_testdir1/ {print $5}')
16302         testdir2_size=$(ls -l $DIR/${tdir} |
16303                 awk '/stats_testdir2/ {print $5}')
16304
16305         testdir1_size=$(order_2 $testdir1_size)
16306         testdir2_size=$(order_2 $testdir2_size)
16307
16308         testdir1_size=$(size_in_KMGT $testdir1_size)
16309         testdir2_size=$(size_in_KMGT $testdir2_size)
16310
16311         echo "source rename dir size: ${testdir1_size}"
16312         echo "target rename dir size: ${testdir2_size}"
16313
16314         eval $cmd || error "$cmd failed"
16315         local crossdir=$($cmd | grep 'crossdir')
16316         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16317         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16318         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16319         [[ $src_sample -eq 1 ]] ||
16320                 error "crossdir_rename_size error $src_sample"
16321         [[ $tgt_sample -eq 1 ]] ||
16322                 error "crossdir_rename_size error $tgt_sample"
16323         echo "Check cross dir rename stats success"
16324         rm -rf $DIR/${tdir}
16325 }
16326 run_test 133d "Verifying rename_stats ========================================"
16327
16328 test_133e() {
16329         remote_mds_nodsh && skip "remote MDS with nodsh"
16330         remote_ost_nodsh && skip "remote OST with nodsh"
16331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16332
16333         local testdir=$DIR/${tdir}/stats_testdir
16334         local ctr f0 f1 bs=32768 count=42 sum
16335
16336         mkdir -p ${testdir} || error "mkdir failed"
16337
16338         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16339
16340         for ctr in {write,read}_bytes; do
16341                 sync
16342                 cancel_lru_locks osc
16343
16344                 do_facet ost1 $LCTL set_param -n \
16345                         "obdfilter.*.exports.clear=clear"
16346
16347                 if [ $ctr = write_bytes ]; then
16348                         f0=/dev/zero
16349                         f1=${testdir}/${tfile}
16350                 else
16351                         f0=${testdir}/${tfile}
16352                         f1=/dev/null
16353                 fi
16354
16355                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16356                         error "dd failed"
16357                 sync
16358                 cancel_lru_locks osc
16359
16360                 sum=$(do_facet ost1 $LCTL get_param \
16361                         "obdfilter.*.exports.*.stats" |
16362                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16363                                 $1 == ctr { sum += $7 }
16364                                 END { printf("%0.0f", sum) }')
16365
16366                 if ((sum != bs * count)); then
16367                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16368                 fi
16369         done
16370
16371         rm -rf $DIR/${tdir}
16372 }
16373 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16374
16375 test_133f() {
16376         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16377                 skip "too old lustre for get_param -R ($facet_ver)"
16378
16379         # verifying readability.
16380         $LCTL get_param -R '*' &> /dev/null
16381
16382         # Verifing writability with badarea_io.
16383         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16384         local skipped_params='force_lbug|changelog_mask|daemon_file'
16385         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16386                 egrep -v "$skipped_params" |
16387                 xargs -n 1 find $proc_dirs -name |
16388                 xargs -n 1 badarea_io ||
16389                 error "client badarea_io failed"
16390
16391         # remount the FS in case writes/reads /proc break the FS
16392         cleanup || error "failed to unmount"
16393         setup || error "failed to setup"
16394 }
16395 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16396
16397 test_133g() {
16398         remote_mds_nodsh && skip "remote MDS with nodsh"
16399         remote_ost_nodsh && skip "remote OST with nodsh"
16400
16401         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16402         local proc_dirs_str=$(eval echo $proc_dirs)
16403         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16404         local facet
16405         for facet in mds1 ost1; do
16406                 local facet_ver=$(lustre_version_code $facet)
16407                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16408                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16409                 else
16410                         log "$facet: too old lustre for get_param -R"
16411                 fi
16412                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16413                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16414                                 tr -d = | egrep -v $skipped_params |
16415                                 xargs -n 1 find $proc_dirs_str -name |
16416                                 xargs -n 1 badarea_io" ||
16417                                         error "$facet badarea_io failed"
16418                 else
16419                         skip_noexit "$facet: too old lustre for get_param -R"
16420                 fi
16421         done
16422
16423         # remount the FS in case writes/reads /proc break the FS
16424         cleanup || error "failed to unmount"
16425         setup || error "failed to setup"
16426 }
16427 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16428
16429 test_133h() {
16430         remote_mds_nodsh && skip "remote MDS with nodsh"
16431         remote_ost_nodsh && skip "remote OST with nodsh"
16432         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16433                 skip "Need MDS version at least 2.9.54"
16434
16435         local facet
16436         for facet in client mds1 ost1; do
16437                 # Get the list of files that are missing the terminating newline
16438                 local plist=$(do_facet $facet
16439                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16440                 local ent
16441                 for ent in $plist; do
16442                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16443                                 awk -v FS='\v' -v RS='\v\v' \
16444                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16445                                         print FILENAME}'" 2>/dev/null)
16446                         [ -z $missing ] || {
16447                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16448                                 error "file does not end with newline: $facet-$ent"
16449                         }
16450                 done
16451         done
16452 }
16453 run_test 133h "Proc files should end with newlines"
16454
16455 test_134a() {
16456         remote_mds_nodsh && skip "remote MDS with nodsh"
16457         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16458                 skip "Need MDS version at least 2.7.54"
16459
16460         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16461         cancel_lru_locks mdc
16462
16463         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16464         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16465         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16466
16467         local nr=1000
16468         createmany -o $DIR/$tdir/f $nr ||
16469                 error "failed to create $nr files in $DIR/$tdir"
16470         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16471
16472         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16473         do_facet mds1 $LCTL set_param fail_loc=0x327
16474         do_facet mds1 $LCTL set_param fail_val=500
16475         touch $DIR/$tdir/m
16476
16477         echo "sleep 10 seconds ..."
16478         sleep 10
16479         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16480
16481         do_facet mds1 $LCTL set_param fail_loc=0
16482         do_facet mds1 $LCTL set_param fail_val=0
16483         [ $lck_cnt -lt $unused ] ||
16484                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16485
16486         rm $DIR/$tdir/m
16487         unlinkmany $DIR/$tdir/f $nr
16488 }
16489 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16490
16491 test_134b() {
16492         remote_mds_nodsh && skip "remote MDS with nodsh"
16493         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16494                 skip "Need MDS version at least 2.7.54"
16495
16496         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16497         cancel_lru_locks mdc
16498
16499         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16500                         ldlm.lock_reclaim_threshold_mb)
16501         # disable reclaim temporarily
16502         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16503
16504         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16505         do_facet mds1 $LCTL set_param fail_loc=0x328
16506         do_facet mds1 $LCTL set_param fail_val=500
16507
16508         $LCTL set_param debug=+trace
16509
16510         local nr=600
16511         createmany -o $DIR/$tdir/f $nr &
16512         local create_pid=$!
16513
16514         echo "Sleep $TIMEOUT seconds ..."
16515         sleep $TIMEOUT
16516         if ! ps -p $create_pid  > /dev/null 2>&1; then
16517                 do_facet mds1 $LCTL set_param fail_loc=0
16518                 do_facet mds1 $LCTL set_param fail_val=0
16519                 do_facet mds1 $LCTL set_param \
16520                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16521                 error "createmany finished incorrectly!"
16522         fi
16523         do_facet mds1 $LCTL set_param fail_loc=0
16524         do_facet mds1 $LCTL set_param fail_val=0
16525         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16526         wait $create_pid || return 1
16527
16528         unlinkmany $DIR/$tdir/f $nr
16529 }
16530 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16531
16532 test_135() {
16533         remote_mds_nodsh && skip "remote MDS with nodsh"
16534         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16535                 skip "Need MDS version at least 2.13.50"
16536         local fname
16537
16538         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16539
16540 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16541         #set only one record at plain llog
16542         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16543
16544         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16545
16546         #fill already existed plain llog each 64767
16547         #wrapping whole catalog
16548         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16549
16550         createmany -o $DIR/$tdir/$tfile_ 64700
16551         for (( i = 0; i < 64700; i = i + 2 ))
16552         do
16553                 rm $DIR/$tdir/$tfile_$i &
16554                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16555                 local pid=$!
16556                 wait $pid
16557         done
16558
16559         #waiting osp synchronization
16560         wait_delete_completed
16561 }
16562 run_test 135 "Race catalog processing"
16563
16564 test_136() {
16565         remote_mds_nodsh && skip "remote MDS with nodsh"
16566         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16567                 skip "Need MDS version at least 2.13.50"
16568         local fname
16569
16570         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16571         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16572         #set only one record at plain llog
16573 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16574         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16575
16576         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16577
16578         #fill already existed 2 plain llogs each 64767
16579         #wrapping whole catalog
16580         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16581         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16582         wait_delete_completed
16583
16584         createmany -o $DIR/$tdir/$tfile_ 10
16585         sleep 25
16586
16587         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16588         for (( i = 0; i < 10; i = i + 3 ))
16589         do
16590                 rm $DIR/$tdir/$tfile_$i &
16591                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16592                 local pid=$!
16593                 wait $pid
16594                 sleep 7
16595                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16596         done
16597
16598         #waiting osp synchronization
16599         wait_delete_completed
16600 }
16601 run_test 136 "Race catalog processing 2"
16602
16603 test_140() { #bug-17379
16604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16605
16606         test_mkdir $DIR/$tdir
16607         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16608         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16609
16610         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16611         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16612         local i=0
16613         while i=$((i + 1)); do
16614                 test_mkdir $i
16615                 cd $i || error "Changing to $i"
16616                 ln -s ../stat stat || error "Creating stat symlink"
16617                 # Read the symlink until ELOOP present,
16618                 # not LBUGing the system is considered success,
16619                 # we didn't overrun the stack.
16620                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16621                 if [ $ret -ne 0 ]; then
16622                         if [ $ret -eq 40 ]; then
16623                                 break  # -ELOOP
16624                         else
16625                                 error "Open stat symlink"
16626                                         return
16627                         fi
16628                 fi
16629         done
16630         i=$((i - 1))
16631         echo "The symlink depth = $i"
16632         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16633                 error "Invalid symlink depth"
16634
16635         # Test recursive symlink
16636         ln -s symlink_self symlink_self
16637         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16638         echo "open symlink_self returns $ret"
16639         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16640 }
16641 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16642
16643 test_150a() {
16644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16645
16646         local TF="$TMP/$tfile"
16647
16648         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16649         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16650         cp $TF $DIR/$tfile
16651         cancel_lru_locks $OSC
16652         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16653         remount_client $MOUNT
16654         df -P $MOUNT
16655         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16656
16657         $TRUNCATE $TF 6000
16658         $TRUNCATE $DIR/$tfile 6000
16659         cancel_lru_locks $OSC
16660         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16661
16662         echo "12345" >>$TF
16663         echo "12345" >>$DIR/$tfile
16664         cancel_lru_locks $OSC
16665         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16666
16667         echo "12345" >>$TF
16668         echo "12345" >>$DIR/$tfile
16669         cancel_lru_locks $OSC
16670         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16671 }
16672 run_test 150a "truncate/append tests"
16673
16674 test_150b() {
16675         check_set_fallocate_or_skip
16676         local out
16677
16678         touch $DIR/$tfile
16679         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16680         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16681                 skip_eopnotsupp "$out|check_fallocate failed"
16682 }
16683 run_test 150b "Verify fallocate (prealloc) functionality"
16684
16685 test_150bb() {
16686         check_set_fallocate_or_skip
16687
16688         touch $DIR/$tfile
16689         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16690         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16691         > $DIR/$tfile
16692         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16693         # precomputed md5sum for 20MB of zeroes
16694         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16695         local sum=($(md5sum $DIR/$tfile))
16696
16697         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16698
16699         check_set_fallocate 1
16700
16701         > $DIR/$tfile
16702         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16703         sum=($(md5sum $DIR/$tfile))
16704
16705         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16706 }
16707 run_test 150bb "Verify fallocate modes both zero space"
16708
16709 test_150c() {
16710         check_set_fallocate_or_skip
16711         local striping="-c2"
16712
16713         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16714         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16715         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16716         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16717         local want=$((OSTCOUNT * 1048576))
16718
16719         # Must allocate all requested space, not more than 5% extra
16720         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16721                 error "bytes $bytes is not $want"
16722
16723         rm -f $DIR/$tfile
16724
16725         echo "verify fallocate on PFL file"
16726
16727         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16728
16729         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16730                 error "Create $DIR/$tfile failed"
16731         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16732         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16733         want=$((512 * 1048576))
16734
16735         # Must allocate all requested space, not more than 5% extra
16736         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16737                 error "bytes $bytes is not $want"
16738 }
16739 run_test 150c "Verify fallocate Size and Blocks"
16740
16741 test_150d() {
16742         check_set_fallocate_or_skip
16743         local striping="-c2"
16744
16745         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16746
16747         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16748         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16749                 error "setstripe failed"
16750         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16751         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16752         local want=$((OSTCOUNT * 1048576))
16753
16754         # Must allocate all requested space, not more than 5% extra
16755         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16756                 error "bytes $bytes is not $want"
16757 }
16758 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16759
16760 test_150e() {
16761         check_set_fallocate_or_skip
16762
16763         echo "df before:"
16764         $LFS df
16765         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16766         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16767                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16768
16769         # Find OST with Minimum Size
16770         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16771                        sort -un | head -1)
16772
16773         # Get 100MB per OST of the available space to reduce run time
16774         # else 60% of the available space if we are running SLOW tests
16775         if [ $SLOW == "no" ]; then
16776                 local space=$((1024 * 100 * OSTCOUNT))
16777         else
16778                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16779         fi
16780
16781         fallocate -l${space}k $DIR/$tfile ||
16782                 error "fallocate ${space}k $DIR/$tfile failed"
16783         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16784
16785         # get size immediately after fallocate. This should be correctly
16786         # updated
16787         local size=$(stat -c '%s' $DIR/$tfile)
16788         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16789
16790         # Sleep for a while for statfs to get updated. And not pull from cache.
16791         sleep 2
16792
16793         echo "df after fallocate:"
16794         $LFS df
16795
16796         (( size / 1024 == space )) || error "size $size != requested $space"
16797         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16798                 error "used $used < space $space"
16799
16800         rm $DIR/$tfile || error "rm failed"
16801         sync
16802         wait_delete_completed
16803
16804         echo "df after unlink:"
16805         $LFS df
16806 }
16807 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16808
16809 test_150f() {
16810         local size
16811         local blocks
16812         local want_size_before=20480 # in bytes
16813         local want_blocks_before=40 # 512 sized blocks
16814         local want_blocks_after=24  # 512 sized blocks
16815         local length=$(((want_blocks_before - want_blocks_after) * 512))
16816
16817         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16818                 skip "need at least 2.14.0 for fallocate punch"
16819
16820         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16821                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16822         fi
16823
16824         check_set_fallocate_or_skip
16825         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16826
16827         [[ "x$DOM" == "xyes" ]] &&
16828                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16829
16830         echo "Verify fallocate punch: Range within the file range"
16831         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16832                 error "dd failed for bs 4096 and count 5"
16833
16834         # Call fallocate with punch range which is within the file range
16835         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16836                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16837         # client must see changes immediately after fallocate
16838         size=$(stat -c '%s' $DIR/$tfile)
16839         blocks=$(stat -c '%b' $DIR/$tfile)
16840
16841         # Verify punch worked.
16842         (( blocks == want_blocks_after )) ||
16843                 error "punch failed: blocks $blocks != $want_blocks_after"
16844
16845         (( size == want_size_before )) ||
16846                 error "punch failed: size $size != $want_size_before"
16847
16848         # Verify there is hole in file
16849         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16850         # precomputed md5sum
16851         local expect="4a9a834a2db02452929c0a348273b4aa"
16852
16853         cksum=($(md5sum $DIR/$tfile))
16854         [[ "${cksum[0]}" == "$expect" ]] ||
16855                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16856
16857         # Start second sub-case for fallocate punch.
16858         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16859         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16860                 error "dd failed for bs 4096 and count 5"
16861
16862         # Punch range less than block size will have no change in block count
16863         want_blocks_after=40  # 512 sized blocks
16864
16865         # Punch overlaps two blocks and less than blocksize
16866         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16867                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16868         size=$(stat -c '%s' $DIR/$tfile)
16869         blocks=$(stat -c '%b' $DIR/$tfile)
16870
16871         # Verify punch worked.
16872         (( blocks == want_blocks_after )) ||
16873                 error "punch failed: blocks $blocks != $want_blocks_after"
16874
16875         (( size == want_size_before )) ||
16876                 error "punch failed: size $size != $want_size_before"
16877
16878         # Verify if range is really zero'ed out. We expect Zeros.
16879         # precomputed md5sum
16880         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16881         cksum=($(md5sum $DIR/$tfile))
16882         [[ "${cksum[0]}" == "$expect" ]] ||
16883                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16884 }
16885 run_test 150f "Verify fallocate punch functionality"
16886
16887 test_150g() {
16888         local space
16889         local size
16890         local blocks
16891         local blocks_after
16892         local size_after
16893         local BS=4096 # Block size in bytes
16894
16895         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16896                 skip "need at least 2.14.0 for fallocate punch"
16897
16898         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16899                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16900         fi
16901
16902         check_set_fallocate_or_skip
16903         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16904
16905         if [[ "x$DOM" == "xyes" ]]; then
16906                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16907                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16908         else
16909                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16910                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16911         fi
16912
16913         # Get 100MB per OST of the available space to reduce run time
16914         # else 60% of the available space if we are running SLOW tests
16915         if [ $SLOW == "no" ]; then
16916                 space=$((1024 * 100 * OSTCOUNT))
16917         else
16918                 # Find OST with Minimum Size
16919                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16920                         sort -un | head -1)
16921                 echo "min size OST: $space"
16922                 space=$(((space * 60)/100 * OSTCOUNT))
16923         fi
16924         # space in 1k units, round to 4k blocks
16925         local blkcount=$((space * 1024 / $BS))
16926
16927         echo "Verify fallocate punch: Very large Range"
16928         fallocate -l${space}k $DIR/$tfile ||
16929                 error "fallocate ${space}k $DIR/$tfile failed"
16930         # write 1M at the end, start and in the middle
16931         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16932                 error "dd failed: bs $BS count 256"
16933         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16934                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16935         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16936                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16937
16938         # Gather stats.
16939         size=$(stat -c '%s' $DIR/$tfile)
16940
16941         # gather punch length.
16942         local punch_size=$((size - (BS * 2)))
16943
16944         echo "punch_size = $punch_size"
16945         echo "size - punch_size: $((size - punch_size))"
16946         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16947
16948         # Call fallocate to punch all except 2 blocks. We leave the
16949         # first and the last block
16950         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16951         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16952                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16953
16954         size_after=$(stat -c '%s' $DIR/$tfile)
16955         blocks_after=$(stat -c '%b' $DIR/$tfile)
16956
16957         # Verify punch worked.
16958         # Size should be kept
16959         (( size == size_after )) ||
16960                 error "punch failed: size $size != $size_after"
16961
16962         # two 4k data blocks to remain plus possible 1 extra extent block
16963         (( blocks_after <= ((BS / 512) * 3) )) ||
16964                 error "too many blocks remains: $blocks_after"
16965
16966         # Verify that file has hole between the first and the last blocks
16967         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16968         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16969
16970         echo "Hole at [$hole_start, $hole_end)"
16971         (( hole_start == BS )) ||
16972                 error "no hole at offset $BS after punch"
16973
16974         (( hole_end == BS + punch_size )) ||
16975                 error "data at offset $hole_end < $((BS + punch_size))"
16976 }
16977 run_test 150g "Verify fallocate punch on large range"
16978
16979 test_150h() {
16980         local file=$DIR/$tfile
16981         local size
16982
16983         check_set_fallocate_or_skip
16984         statx_supported || skip_env "Test must be statx() syscall supported"
16985
16986         # fallocate() does not update the size information on the MDT
16987         fallocate -l 16K $file || error "failed to fallocate $file"
16988         cancel_lru_locks $OSC
16989         # STATX with cached-always mode will not send glimpse RPCs to OST,
16990         # it uses the caching attrs on the client side as much as possible.
16991         size=$($STATX --cached=always -c %s $file)
16992         [ $size == 16384 ] ||
16993                 error "size after fallocate() is $size, expected 16384"
16994 }
16995 run_test 150h "Verify extend fallocate updates the file size"
16996
16997 #LU-2902 roc_hit was not able to read all values from lproc
16998 function roc_hit_init() {
16999         local list=$(comma_list $(osts_nodes))
17000         local dir=$DIR/$tdir-check
17001         local file=$dir/$tfile
17002         local BEFORE
17003         local AFTER
17004         local idx
17005
17006         test_mkdir $dir
17007         #use setstripe to do a write to every ost
17008         for i in $(seq 0 $((OSTCOUNT-1))); do
17009                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
17010                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
17011                 idx=$(printf %04x $i)
17012                 BEFORE=$(get_osd_param $list *OST*$idx stats |
17013                         awk '$1 == "cache_access" {sum += $7}
17014                                 END { printf("%0.0f", sum) }')
17015
17016                 cancel_lru_locks osc
17017                 cat $file >/dev/null
17018
17019                 AFTER=$(get_osd_param $list *OST*$idx stats |
17020                         awk '$1 == "cache_access" {sum += $7}
17021                                 END { printf("%0.0f", sum) }')
17022
17023                 echo BEFORE:$BEFORE AFTER:$AFTER
17024                 if ! let "AFTER - BEFORE == 4"; then
17025                         rm -rf $dir
17026                         error "roc_hit is not safe to use"
17027                 fi
17028                 rm $file
17029         done
17030
17031         rm -rf $dir
17032 }
17033
17034 function roc_hit() {
17035         local list=$(comma_list $(osts_nodes))
17036         echo $(get_osd_param $list '' stats |
17037                 awk '$1 == "cache_hit" {sum += $7}
17038                         END { printf("%0.0f", sum) }')
17039 }
17040
17041 function set_cache() {
17042         local on=1
17043
17044         if [ "$2" == "off" ]; then
17045                 on=0;
17046         fi
17047         local list=$(comma_list $(osts_nodes))
17048         set_osd_param $list '' $1_cache_enable $on
17049
17050         cancel_lru_locks osc
17051 }
17052
17053 test_151() {
17054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17055         remote_ost_nodsh && skip "remote OST with nodsh"
17056         (( CLIENT_VERSION == OST1_VERSION )) ||
17057                 skip "LU-13081: no interop testing for OSS cache"
17058
17059         local CPAGES=3
17060         local list=$(comma_list $(osts_nodes))
17061
17062         # check whether obdfilter is cache capable at all
17063         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
17064                 skip "not cache-capable obdfilter"
17065         fi
17066
17067         # check cache is enabled on all obdfilters
17068         if get_osd_param $list '' read_cache_enable | grep 0; then
17069                 skip "oss cache is disabled"
17070         fi
17071
17072         set_osd_param $list '' writethrough_cache_enable 1
17073
17074         # check write cache is enabled on all obdfilters
17075         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
17076                 skip "oss write cache is NOT enabled"
17077         fi
17078
17079         roc_hit_init
17080
17081         #define OBD_FAIL_OBD_NO_LRU  0x609
17082         do_nodes $list $LCTL set_param fail_loc=0x609
17083
17084         # pages should be in the case right after write
17085         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
17086                 error "dd failed"
17087
17088         local BEFORE=$(roc_hit)
17089         cancel_lru_locks osc
17090         cat $DIR/$tfile >/dev/null
17091         local AFTER=$(roc_hit)
17092
17093         do_nodes $list $LCTL set_param fail_loc=0
17094
17095         if ! let "AFTER - BEFORE == CPAGES"; then
17096                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
17097         fi
17098
17099         cancel_lru_locks osc
17100         # invalidates OST cache
17101         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
17102         set_osd_param $list '' read_cache_enable 0
17103         cat $DIR/$tfile >/dev/null
17104
17105         # now data shouldn't be found in the cache
17106         BEFORE=$(roc_hit)
17107         cancel_lru_locks osc
17108         cat $DIR/$tfile >/dev/null
17109         AFTER=$(roc_hit)
17110         if let "AFTER - BEFORE != 0"; then
17111                 error "IN CACHE: before: $BEFORE, after: $AFTER"
17112         fi
17113
17114         set_osd_param $list '' read_cache_enable 1
17115         rm -f $DIR/$tfile
17116 }
17117 run_test 151 "test cache on oss and controls ==============================="
17118
17119 test_152() {
17120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17121
17122         local TF="$TMP/$tfile"
17123
17124         # simulate ENOMEM during write
17125 #define OBD_FAIL_OST_NOMEM      0x226
17126         lctl set_param fail_loc=0x80000226
17127         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
17128         cp $TF $DIR/$tfile
17129         sync || error "sync failed"
17130         lctl set_param fail_loc=0
17131
17132         # discard client's cache
17133         cancel_lru_locks osc
17134
17135         # simulate ENOMEM during read
17136         lctl set_param fail_loc=0x80000226
17137         cmp $TF $DIR/$tfile || error "cmp failed"
17138         lctl set_param fail_loc=0
17139
17140         rm -f $TF
17141 }
17142 run_test 152 "test read/write with enomem ============================"
17143
17144 test_153() {
17145         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
17146 }
17147 run_test 153 "test if fdatasync does not crash ======================="
17148
17149 dot_lustre_fid_permission_check() {
17150         local fid=$1
17151         local ffid=$MOUNT/.lustre/fid/$fid
17152         local test_dir=$2
17153
17154         echo "stat fid $fid"
17155         stat $ffid || error "stat $ffid failed."
17156         echo "touch fid $fid"
17157         touch $ffid || error "touch $ffid failed."
17158         echo "write to fid $fid"
17159         cat /etc/hosts > $ffid || error "write $ffid failed."
17160         echo "read fid $fid"
17161         diff /etc/hosts $ffid || error "read $ffid failed."
17162         echo "append write to fid $fid"
17163         cat /etc/hosts >> $ffid || error "append write $ffid failed."
17164         echo "rename fid $fid"
17165         mv $ffid $test_dir/$tfile.1 &&
17166                 error "rename $ffid to $tfile.1 should fail."
17167         touch $test_dir/$tfile.1
17168         mv $test_dir/$tfile.1 $ffid &&
17169                 error "rename $tfile.1 to $ffid should fail."
17170         rm -f $test_dir/$tfile.1
17171         echo "truncate fid $fid"
17172         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
17173         echo "link fid $fid"
17174         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
17175         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
17176                 id $USER0 || skip_env "missing user $USER0"
17177                 echo "setfacl fid $fid"
17178                 setfacl -R -m u:$USER0:rwx $ffid ||
17179                         error "setfacl $ffid failed"
17180                 echo "getfacl fid $fid"
17181                 getfacl $ffid || error "getfacl $ffid failed."
17182         fi
17183         echo "unlink fid $fid"
17184         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
17185         echo "mknod fid $fid"
17186         mknod $ffid c 1 3 && error "mknod $ffid should fail."
17187
17188         fid=[0xf00000400:0x1:0x0]
17189         ffid=$MOUNT/.lustre/fid/$fid
17190
17191         echo "stat non-exist fid $fid"
17192         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
17193         echo "write to non-exist fid $fid"
17194         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
17195         echo "link new fid $fid"
17196         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
17197
17198         mkdir -p $test_dir/$tdir
17199         touch $test_dir/$tdir/$tfile
17200         fid=$($LFS path2fid $test_dir/$tdir)
17201         rc=$?
17202         [ $rc -ne 0 ] &&
17203                 error "error: could not get fid for $test_dir/$dir/$tfile."
17204
17205         ffid=$MOUNT/.lustre/fid/$fid
17206
17207         echo "ls $fid"
17208         ls $ffid || error "ls $ffid failed."
17209         echo "touch $fid/$tfile.1"
17210         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17211
17212         echo "touch $MOUNT/.lustre/fid/$tfile"
17213         touch $MOUNT/.lustre/fid/$tfile && \
17214                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17215
17216         echo "setxattr to $MOUNT/.lustre/fid"
17217         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17218
17219         echo "listxattr for $MOUNT/.lustre/fid"
17220         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17221
17222         echo "delxattr from $MOUNT/.lustre/fid"
17223         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17224
17225         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17226         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17227                 error "touch invalid fid should fail."
17228
17229         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17230         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17231                 error "touch non-normal fid should fail."
17232
17233         echo "rename $tdir to $MOUNT/.lustre/fid"
17234         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17235                 error "rename to $MOUNT/.lustre/fid should fail."
17236
17237         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17238         then            # LU-3547
17239                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17240                 local new_obf_mode=777
17241
17242                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17243                 chmod $new_obf_mode $DIR/.lustre/fid ||
17244                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17245
17246                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17247                 [ $obf_mode -eq $new_obf_mode ] ||
17248                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17249
17250                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17251                 chmod $old_obf_mode $DIR/.lustre/fid ||
17252                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17253         fi
17254
17255         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17256         fid=$($LFS path2fid $test_dir/$tfile-2)
17257
17258         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17259         then # LU-5424
17260                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17261                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17262                         error "create lov data thru .lustre failed"
17263         fi
17264         echo "cp /etc/passwd $test_dir/$tfile-2"
17265         cp /etc/passwd $test_dir/$tfile-2 ||
17266                 error "copy to $test_dir/$tfile-2 failed."
17267         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17268         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17269                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17270
17271         rm -rf $test_dir/tfile.lnk
17272         rm -rf $test_dir/$tfile-2
17273 }
17274
17275 test_154A() {
17276         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17277                 skip "Need MDS version at least 2.4.1"
17278
17279         local tf=$DIR/$tfile
17280         touch $tf
17281
17282         local fid=$($LFS path2fid $tf)
17283         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17284
17285         # check that we get the same pathname back
17286         local rootpath
17287         local found
17288         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17289                 echo "$rootpath $fid"
17290                 found=$($LFS fid2path $rootpath "$fid")
17291                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17292                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17293         done
17294
17295         # check wrong root path format
17296         rootpath=$MOUNT"_wrong"
17297         found=$($LFS fid2path $rootpath "$fid")
17298         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17299 }
17300 run_test 154A "lfs path2fid and fid2path basic checks"
17301
17302 test_154B() {
17303         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17304                 skip "Need MDS version at least 2.4.1"
17305
17306         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17307         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17308         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17309         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17310
17311         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17312         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17313
17314         # check that we get the same pathname
17315         echo "PFID: $PFID, name: $name"
17316         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17317         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17318         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17319                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17320
17321         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17322 }
17323 run_test 154B "verify the ll_decode_linkea tool"
17324
17325 test_154a() {
17326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17327         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17328         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17329                 skip "Need MDS version at least 2.2.51"
17330         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17331
17332         cp /etc/hosts $DIR/$tfile
17333
17334         fid=$($LFS path2fid $DIR/$tfile)
17335         rc=$?
17336         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17337
17338         dot_lustre_fid_permission_check "$fid" $DIR ||
17339                 error "dot lustre permission check $fid failed"
17340
17341         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17342
17343         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17344
17345         touch $MOUNT/.lustre/file &&
17346                 error "creation is not allowed under .lustre"
17347
17348         mkdir $MOUNT/.lustre/dir &&
17349                 error "mkdir is not allowed under .lustre"
17350
17351         rm -rf $DIR/$tfile
17352 }
17353 run_test 154a "Open-by-FID"
17354
17355 test_154b() {
17356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17357         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17359         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17360                 skip "Need MDS version at least 2.2.51"
17361
17362         local remote_dir=$DIR/$tdir/remote_dir
17363         local MDTIDX=1
17364         local rc=0
17365
17366         mkdir -p $DIR/$tdir
17367         $LFS mkdir -i $MDTIDX $remote_dir ||
17368                 error "create remote directory failed"
17369
17370         cp /etc/hosts $remote_dir/$tfile
17371
17372         fid=$($LFS path2fid $remote_dir/$tfile)
17373         rc=$?
17374         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17375
17376         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17377                 error "dot lustre permission check $fid failed"
17378         rm -rf $DIR/$tdir
17379 }
17380 run_test 154b "Open-by-FID for remote directory"
17381
17382 test_154c() {
17383         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17384                 skip "Need MDS version at least 2.4.1"
17385
17386         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17387         local FID1=$($LFS path2fid $DIR/$tfile.1)
17388         local FID2=$($LFS path2fid $DIR/$tfile.2)
17389         local FID3=$($LFS path2fid $DIR/$tfile.3)
17390
17391         local N=1
17392         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17393                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17394                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17395                 local want=FID$N
17396                 [ "$FID" = "${!want}" ] ||
17397                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17398                 N=$((N + 1))
17399         done
17400
17401         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17402         do
17403                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17404                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17405                 N=$((N + 1))
17406         done
17407 }
17408 run_test 154c "lfs path2fid and fid2path multiple arguments"
17409
17410 test_154d() {
17411         remote_mds_nodsh && skip "remote MDS with nodsh"
17412         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17413                 skip "Need MDS version at least 2.5.53"
17414
17415         if remote_mds; then
17416                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17417         else
17418                 nid="0@lo"
17419         fi
17420         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17421         local fd
17422         local cmd
17423
17424         rm -f $DIR/$tfile
17425         touch $DIR/$tfile
17426
17427         local fid=$($LFS path2fid $DIR/$tfile)
17428         # Open the file
17429         fd=$(free_fd)
17430         cmd="exec $fd<$DIR/$tfile"
17431         eval $cmd
17432         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17433         echo "$fid_list" | grep "$fid"
17434         rc=$?
17435
17436         cmd="exec $fd>/dev/null"
17437         eval $cmd
17438         if [ $rc -ne 0 ]; then
17439                 error "FID $fid not found in open files list $fid_list"
17440         fi
17441 }
17442 run_test 154d "Verify open file fid"
17443
17444 test_154e()
17445 {
17446         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17447                 skip "Need MDS version at least 2.6.50"
17448
17449         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17450                 error ".lustre returned by readdir"
17451         fi
17452 }
17453 run_test 154e ".lustre is not returned by readdir"
17454
17455 test_154f() {
17456         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17457
17458         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17459         mkdir_on_mdt0 $DIR/$tdir
17460         # test dirs inherit from its stripe
17461         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17462         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17463         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17464         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17465         touch $DIR/f
17466
17467         # get fid of parents
17468         local FID0=$($LFS path2fid $DIR/$tdir)
17469         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17470         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17471         local FID3=$($LFS path2fid $DIR)
17472
17473         # check that path2fid --parents returns expected <parent_fid>/name
17474         # 1) test for a directory (single parent)
17475         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17476         [ "$parent" == "$FID0/foo1" ] ||
17477                 error "expected parent: $FID0/foo1, got: $parent"
17478
17479         # 2) test for a file with nlink > 1 (multiple parents)
17480         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17481         echo "$parent" | grep -F "$FID1/$tfile" ||
17482                 error "$FID1/$tfile not returned in parent list"
17483         echo "$parent" | grep -F "$FID2/link" ||
17484                 error "$FID2/link not returned in parent list"
17485
17486         # 3) get parent by fid
17487         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17488         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17489         echo "$parent" | grep -F "$FID1/$tfile" ||
17490                 error "$FID1/$tfile not returned in parent list (by fid)"
17491         echo "$parent" | grep -F "$FID2/link" ||
17492                 error "$FID2/link not returned in parent list (by fid)"
17493
17494         # 4) test for entry in root directory
17495         parent=$($LFS path2fid --parents $DIR/f)
17496         echo "$parent" | grep -F "$FID3/f" ||
17497                 error "$FID3/f not returned in parent list"
17498
17499         # 5) test it on root directory
17500         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17501                 error "$MOUNT should not have parents"
17502
17503         # enable xattr caching and check that linkea is correctly updated
17504         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17505         save_lustre_params client "llite.*.xattr_cache" > $save
17506         lctl set_param llite.*.xattr_cache 1
17507
17508         # 6.1) linkea update on rename
17509         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17510
17511         # get parents by fid
17512         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17513         # foo1 should no longer be returned in parent list
17514         echo "$parent" | grep -F "$FID1" &&
17515                 error "$FID1 should no longer be in parent list"
17516         # the new path should appear
17517         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17518                 error "$FID2/$tfile.moved is not in parent list"
17519
17520         # 6.2) linkea update on unlink
17521         rm -f $DIR/$tdir/foo2/link
17522         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17523         # foo2/link should no longer be returned in parent list
17524         echo "$parent" | grep -F "$FID2/link" &&
17525                 error "$FID2/link should no longer be in parent list"
17526         true
17527
17528         rm -f $DIR/f
17529         restore_lustre_params < $save
17530         rm -f $save
17531 }
17532 run_test 154f "get parent fids by reading link ea"
17533
17534 test_154g()
17535 {
17536         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17537            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17538                 skip "Need MDS version at least 2.6.92"
17539
17540         mkdir_on_mdt0 $DIR/$tdir
17541         llapi_fid_test -d $DIR/$tdir
17542 }
17543 run_test 154g "various llapi FID tests"
17544
17545 test_154h()
17546 {
17547         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17548                 skip "Need client at least version 2.15.55.1"
17549
17550         # Create an empty file
17551         touch $DIR/$tfile
17552
17553         # Get FID (interactive mode) and save under $TMP/$tfile.log
17554         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17555                 path2fid $DIR/$tfile
17556         EOF
17557
17558         fid=$(cat $TMP/$tfile.log)
17559         # $fid should not be empty
17560         [[ ! -z $fid ]] || error "FID is empty"
17561         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17562 }
17563 run_test 154h "Verify interactive path2fid"
17564
17565 test_155_small_load() {
17566     local temp=$TMP/$tfile
17567     local file=$DIR/$tfile
17568
17569     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17570         error "dd of=$temp bs=6096 count=1 failed"
17571     cp $temp $file
17572     cancel_lru_locks $OSC
17573     cmp $temp $file || error "$temp $file differ"
17574
17575     $TRUNCATE $temp 6000
17576     $TRUNCATE $file 6000
17577     cmp $temp $file || error "$temp $file differ (truncate1)"
17578
17579     echo "12345" >>$temp
17580     echo "12345" >>$file
17581     cmp $temp $file || error "$temp $file differ (append1)"
17582
17583     echo "12345" >>$temp
17584     echo "12345" >>$file
17585     cmp $temp $file || error "$temp $file differ (append2)"
17586
17587     rm -f $temp $file
17588     true
17589 }
17590
17591 test_155_big_load() {
17592         remote_ost_nodsh && skip "remote OST with nodsh"
17593
17594         local temp=$TMP/$tfile
17595         local file=$DIR/$tfile
17596
17597         free_min_max
17598         local cache_size=$(do_facet ost$((MAXI+1)) \
17599                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17600
17601         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17602         # pre-set value
17603         if [ -z "$cache_size" ]; then
17604                 cache_size=256
17605         fi
17606         local large_file_size=$((cache_size * 2))
17607
17608         echo "OSS cache size: $cache_size KB"
17609         echo "Large file size: $large_file_size KB"
17610
17611         [ $MAXV -le $large_file_size ] &&
17612                 skip_env "max available OST size needs > $large_file_size KB"
17613
17614         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17615
17616         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17617                 error "dd of=$temp bs=$large_file_size count=1k failed"
17618         cp $temp $file
17619         ls -lh $temp $file
17620         cancel_lru_locks osc
17621         cmp $temp $file || error "$temp $file differ"
17622
17623         rm -f $temp $file
17624         true
17625 }
17626
17627 save_writethrough() {
17628         local facets=$(get_facets OST)
17629
17630         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17631 }
17632
17633 test_155a() {
17634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17635
17636         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17637
17638         save_writethrough $p
17639
17640         set_cache read on
17641         set_cache writethrough on
17642         test_155_small_load
17643         restore_lustre_params < $p
17644         rm -f $p
17645 }
17646 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17647
17648 test_155b() {
17649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17650
17651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17652
17653         save_writethrough $p
17654
17655         set_cache read on
17656         set_cache writethrough off
17657         test_155_small_load
17658         restore_lustre_params < $p
17659         rm -f $p
17660 }
17661 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17662
17663 test_155c() {
17664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17665
17666         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17667
17668         save_writethrough $p
17669
17670         set_cache read off
17671         set_cache writethrough on
17672         test_155_small_load
17673         restore_lustre_params < $p
17674         rm -f $p
17675 }
17676 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17677
17678 test_155d() {
17679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17680
17681         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17682
17683         save_writethrough $p
17684
17685         set_cache read off
17686         set_cache writethrough off
17687         test_155_small_load
17688         restore_lustre_params < $p
17689         rm -f $p
17690 }
17691 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17692
17693 test_155e() {
17694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17695
17696         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17697
17698         save_writethrough $p
17699
17700         set_cache read on
17701         set_cache writethrough on
17702         test_155_big_load
17703         restore_lustre_params < $p
17704         rm -f $p
17705 }
17706 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17707
17708 test_155f() {
17709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17710
17711         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17712
17713         save_writethrough $p
17714
17715         set_cache read on
17716         set_cache writethrough off
17717         test_155_big_load
17718         restore_lustre_params < $p
17719         rm -f $p
17720 }
17721 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17722
17723 test_155g() {
17724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17725
17726         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17727
17728         save_writethrough $p
17729
17730         set_cache read off
17731         set_cache writethrough on
17732         test_155_big_load
17733         restore_lustre_params < $p
17734         rm -f $p
17735 }
17736 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17737
17738 test_155h() {
17739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17740
17741         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17742
17743         save_writethrough $p
17744
17745         set_cache read off
17746         set_cache writethrough off
17747         test_155_big_load
17748         restore_lustre_params < $p
17749         rm -f $p
17750 }
17751 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17752
17753 test_156() {
17754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17755         remote_ost_nodsh && skip "remote OST with nodsh"
17756         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17757                 skip "stats not implemented on old servers"
17758         [ "$ost1_FSTYPE" = "zfs" ] &&
17759                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17760         (( CLIENT_VERSION == OST1_VERSION )) ||
17761                 skip "LU-13081: no interop testing for OSS cache"
17762
17763         local CPAGES=3
17764         local BEFORE
17765         local AFTER
17766         local file="$DIR/$tfile"
17767         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17768
17769         save_writethrough $p
17770         roc_hit_init
17771
17772         log "Turn on read and write cache"
17773         set_cache read on
17774         set_cache writethrough on
17775
17776         log "Write data and read it back."
17777         log "Read should be satisfied from the cache."
17778         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17779         BEFORE=$(roc_hit)
17780         cancel_lru_locks osc
17781         cat $file >/dev/null
17782         AFTER=$(roc_hit)
17783         if ! let "AFTER - BEFORE == CPAGES"; then
17784                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17785         else
17786                 log "cache hits: before: $BEFORE, after: $AFTER"
17787         fi
17788
17789         log "Read again; it should be satisfied from the cache."
17790         BEFORE=$AFTER
17791         cancel_lru_locks osc
17792         cat $file >/dev/null
17793         AFTER=$(roc_hit)
17794         if ! let "AFTER - BEFORE == CPAGES"; then
17795                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17796         else
17797                 log "cache hits:: before: $BEFORE, after: $AFTER"
17798         fi
17799
17800         log "Turn off the read cache and turn on the write cache"
17801         set_cache read off
17802         set_cache writethrough on
17803
17804         log "Read again; it should be satisfied from the cache."
17805         BEFORE=$(roc_hit)
17806         cancel_lru_locks osc
17807         cat $file >/dev/null
17808         AFTER=$(roc_hit)
17809         if ! let "AFTER - BEFORE == CPAGES"; then
17810                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17811         else
17812                 log "cache hits:: before: $BEFORE, after: $AFTER"
17813         fi
17814
17815         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17816                 # > 2.12.56 uses pagecache if cached
17817                 log "Read again; it should not be satisfied from the cache."
17818                 BEFORE=$AFTER
17819                 cancel_lru_locks osc
17820                 cat $file >/dev/null
17821                 AFTER=$(roc_hit)
17822                 if ! let "AFTER - BEFORE == 0"; then
17823                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17824                 else
17825                         log "cache hits:: before: $BEFORE, after: $AFTER"
17826                 fi
17827         fi
17828
17829         log "Write data and read it back."
17830         log "Read should be satisfied from the cache."
17831         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17832         BEFORE=$(roc_hit)
17833         cancel_lru_locks osc
17834         cat $file >/dev/null
17835         AFTER=$(roc_hit)
17836         if ! let "AFTER - BEFORE == CPAGES"; then
17837                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17838         else
17839                 log "cache hits:: before: $BEFORE, after: $AFTER"
17840         fi
17841
17842         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17843                 # > 2.12.56 uses pagecache if cached
17844                 log "Read again; it should not be satisfied from the cache."
17845                 BEFORE=$AFTER
17846                 cancel_lru_locks osc
17847                 cat $file >/dev/null
17848                 AFTER=$(roc_hit)
17849                 if ! let "AFTER - BEFORE == 0"; then
17850                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17851                 else
17852                         log "cache hits:: before: $BEFORE, after: $AFTER"
17853                 fi
17854         fi
17855
17856         log "Turn off read and write cache"
17857         set_cache read off
17858         set_cache writethrough off
17859
17860         log "Write data and read it back"
17861         log "It should not be satisfied from the cache."
17862         rm -f $file
17863         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17864         cancel_lru_locks osc
17865         BEFORE=$(roc_hit)
17866         cat $file >/dev/null
17867         AFTER=$(roc_hit)
17868         if ! let "AFTER - BEFORE == 0"; then
17869                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17870         else
17871                 log "cache hits:: before: $BEFORE, after: $AFTER"
17872         fi
17873
17874         log "Turn on the read cache and turn off the write cache"
17875         set_cache read on
17876         set_cache writethrough off
17877
17878         log "Write data and read it back"
17879         log "It should not be satisfied from the cache."
17880         rm -f $file
17881         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17882         BEFORE=$(roc_hit)
17883         cancel_lru_locks osc
17884         cat $file >/dev/null
17885         AFTER=$(roc_hit)
17886         if ! let "AFTER - BEFORE == 0"; then
17887                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17888         else
17889                 log "cache hits:: before: $BEFORE, after: $AFTER"
17890         fi
17891
17892         log "Read again; it should be satisfied from the cache."
17893         BEFORE=$(roc_hit)
17894         cancel_lru_locks osc
17895         cat $file >/dev/null
17896         AFTER=$(roc_hit)
17897         if ! let "AFTER - BEFORE == CPAGES"; then
17898                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17899         else
17900                 log "cache hits:: before: $BEFORE, after: $AFTER"
17901         fi
17902
17903         restore_lustre_params < $p
17904         rm -f $p $file
17905 }
17906 run_test 156 "Verification of tunables"
17907
17908 test_160a() {
17909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17910         remote_mds_nodsh && skip "remote MDS with nodsh"
17911         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17912                 skip "Need MDS version at least 2.2.0"
17913
17914         changelog_register || error "changelog_register failed"
17915         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17916         changelog_users $SINGLEMDS | grep -q $cl_user ||
17917                 error "User $cl_user not found in changelog_users"
17918
17919         mkdir_on_mdt0 $DIR/$tdir
17920
17921         # change something
17922         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17923         changelog_clear 0 || error "changelog_clear failed"
17924         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17925         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17926         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17927         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17928         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17929         rm $DIR/$tdir/pics/desktop.jpg
17930
17931         echo "verifying changelog mask"
17932         changelog_chmask "-MKDIR"
17933         changelog_chmask "-CLOSE"
17934
17935         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17936         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17937
17938         changelog_chmask "+MKDIR"
17939         changelog_chmask "+CLOSE"
17940
17941         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17942         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17943
17944         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17945         CLOSES=$(changelog_dump | grep -c "CLOSE")
17946         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17947         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17948
17949         # verify contents
17950         echo "verifying target fid"
17951         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17952         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17953         [ "$fidc" == "$fidf" ] ||
17954                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17955         echo "verifying parent fid"
17956         # The FID returned from the Changelog may be the directory shard on
17957         # a different MDT, and not the FID returned by path2fid on the parent.
17958         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17959         # since this is what will matter when recreating this file in the tree.
17960         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17961         local pathp=$($LFS fid2path $MOUNT "$fidp")
17962         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17963                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17964
17965         echo "getting records for $cl_user"
17966         changelog_users $SINGLEMDS
17967         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17968         local nclr=3
17969         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17970                 error "changelog_clear failed"
17971         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17972         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17973         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17974                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17975
17976         local min0_rec=$(changelog_users $SINGLEMDS |
17977                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17978         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17979                           awk '{ print $1; exit; }')
17980
17981         changelog_dump | tail -n 5
17982         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17983         [ $first_rec == $((min0_rec + 1)) ] ||
17984                 error "first index should be $min0_rec + 1 not $first_rec"
17985
17986         # LU-3446 changelog index reset on MDT restart
17987         local cur_rec1=$(changelog_users $SINGLEMDS |
17988                          awk '/^current.index:/ { print $NF }')
17989         changelog_clear 0 ||
17990                 error "clear all changelog records for $cl_user failed"
17991         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17992         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17993                 error "Fail to start $SINGLEMDS"
17994         local cur_rec2=$(changelog_users $SINGLEMDS |
17995                          awk '/^current.index:/ { print $NF }')
17996         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17997         [ $cur_rec1 == $cur_rec2 ] ||
17998                 error "current index should be $cur_rec1 not $cur_rec2"
17999
18000         echo "verifying users from this test are deregistered"
18001         changelog_deregister || error "changelog_deregister failed"
18002         changelog_users $SINGLEMDS | grep -q $cl_user &&
18003                 error "User '$cl_user' still in changelog_users"
18004
18005         # lctl get_param -n mdd.*.changelog_users
18006         # current_index: 144
18007         # ID    index (idle seconds)
18008         # cl3   144   (2) mask=<list>
18009         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
18010                 # this is the normal case where all users were deregistered
18011                 # make sure no new records are added when no users are present
18012                 local last_rec1=$(changelog_users $SINGLEMDS |
18013                                   awk '/^current.index:/ { print $NF }')
18014                 touch $DIR/$tdir/chloe
18015                 local last_rec2=$(changelog_users $SINGLEMDS |
18016                                   awk '/^current.index:/ { print $NF }')
18017                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
18018                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
18019         else
18020                 # any changelog users must be leftovers from a previous test
18021                 changelog_users $SINGLEMDS
18022                 echo "other changelog users; can't verify off"
18023         fi
18024 }
18025 run_test 160a "changelog sanity"
18026
18027 test_160b() { # LU-3587
18028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18029         remote_mds_nodsh && skip "remote MDS with nodsh"
18030         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18031                 skip "Need MDS version at least 2.2.0"
18032
18033         changelog_register || error "changelog_register failed"
18034         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18035         changelog_users $SINGLEMDS | grep -q $cl_user ||
18036                 error "User '$cl_user' not found in changelog_users"
18037
18038         local longname1=$(str_repeat a 255)
18039         local longname2=$(str_repeat b 255)
18040
18041         cd $DIR
18042         echo "creating very long named file"
18043         touch $longname1 || error "create of '$longname1' failed"
18044         echo "renaming very long named file"
18045         mv $longname1 $longname2
18046
18047         changelog_dump | grep RENME | tail -n 5
18048         rm -f $longname2
18049 }
18050 run_test 160b "Verify that very long rename doesn't crash in changelog"
18051
18052 test_160c() {
18053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18054         remote_mds_nodsh && skip "remote MDS with nodsh"
18055
18056         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18057                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18058                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18059                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18060
18061         local rc=0
18062
18063         # Registration step
18064         changelog_register || error "changelog_register failed"
18065
18066         rm -rf $DIR/$tdir
18067         mkdir -p $DIR/$tdir
18068         $MCREATE $DIR/$tdir/foo_160c
18069         changelog_chmask "-TRUNC"
18070         $TRUNCATE $DIR/$tdir/foo_160c 200
18071         changelog_chmask "+TRUNC"
18072         $TRUNCATE $DIR/$tdir/foo_160c 199
18073         changelog_dump | tail -n 5
18074         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
18075         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
18076 }
18077 run_test 160c "verify that changelog log catch the truncate event"
18078
18079 test_160d() {
18080         remote_mds_nodsh && skip "remote MDS with nodsh"
18081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18083         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
18084                 skip "Need MDS version at least 2.7.60"
18085
18086         # Registration step
18087         changelog_register || error "changelog_register failed"
18088
18089         mkdir -p $DIR/$tdir/migrate_dir
18090         changelog_clear 0 || error "changelog_clear failed"
18091
18092         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
18093         changelog_dump | tail -n 5
18094         local migrates=$(changelog_dump | grep -c "MIGRT")
18095         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
18096 }
18097 run_test 160d "verify that changelog log catch the migrate event"
18098
18099 test_160e() {
18100         remote_mds_nodsh && skip "remote MDS with nodsh"
18101
18102         # Create a user
18103         changelog_register || error "changelog_register failed"
18104
18105         local MDT0=$(facet_svc $SINGLEMDS)
18106         local rc
18107
18108         # No user (expect fail)
18109         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
18110         rc=$?
18111         if [ $rc -eq 0 ]; then
18112                 error "Should fail without user"
18113         elif [ $rc -ne 4 ]; then
18114                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
18115         fi
18116
18117         # Delete a future user (expect fail)
18118         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
18119         rc=$?
18120         if [ $rc -eq 0 ]; then
18121                 error "Deleted non-existant user cl77"
18122         elif [ $rc -ne 2 ]; then
18123                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
18124         fi
18125
18126         # Clear to a bad index (1 billion should be safe)
18127         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
18128         rc=$?
18129
18130         if [ $rc -eq 0 ]; then
18131                 error "Successfully cleared to invalid CL index"
18132         elif [ $rc -ne 22 ]; then
18133                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
18134         fi
18135 }
18136 run_test 160e "changelog negative testing (should return errors)"
18137
18138 test_160f() {
18139         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18140         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18141                 skip "Need MDS version at least 2.10.56"
18142
18143         local mdts=$(comma_list $(mdts_nodes))
18144
18145         # Create a user
18146         changelog_register || error "first changelog_register failed"
18147         changelog_register || error "second changelog_register failed"
18148         local cl_users
18149         declare -A cl_user1
18150         declare -A cl_user2
18151         local user_rec1
18152         local user_rec2
18153         local i
18154
18155         # generate some changelog records to accumulate on each MDT
18156         # use all_char because created files should be evenly distributed
18157         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18158                 error "test_mkdir $tdir failed"
18159         log "$(date +%s): creating first files"
18160         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18161                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
18162                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
18163         done
18164
18165         # check changelogs have been generated
18166         local start=$SECONDS
18167         local idle_time=$((MDSCOUNT * 5 + 5))
18168         local nbcl=$(changelog_dump | wc -l)
18169         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18170
18171         for param in "changelog_max_idle_time=$idle_time" \
18172                      "changelog_gc=1" \
18173                      "changelog_min_gc_interval=2" \
18174                      "changelog_min_free_cat_entries=3"; do
18175                 local MDT0=$(facet_svc $SINGLEMDS)
18176                 local var="${param%=*}"
18177                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18178
18179                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18180                 do_nodes $mdts $LCTL set_param mdd.*.$param
18181         done
18182
18183         # force cl_user2 to be idle (1st part), but also cancel the
18184         # cl_user1 records so that it is not evicted later in the test.
18185         local sleep1=$((idle_time / 2))
18186         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
18187         sleep $sleep1
18188
18189         # simulate changelog catalog almost full
18190         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
18191         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
18192
18193         for i in $(seq $MDSCOUNT); do
18194                 cl_users=(${CL_USERS[mds$i]})
18195                 cl_user1[mds$i]="${cl_users[0]}"
18196                 cl_user2[mds$i]="${cl_users[1]}"
18197
18198                 [ -n "${cl_user1[mds$i]}" ] ||
18199                         error "mds$i: no user registered"
18200                 [ -n "${cl_user2[mds$i]}" ] ||
18201                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18202
18203                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18204                 [ -n "$user_rec1" ] ||
18205                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18206                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18207                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18208                 [ -n "$user_rec2" ] ||
18209                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18210                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18211                      "$user_rec1 + 2 == $user_rec2"
18212                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18213                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18214                               "$user_rec1 + 2, but is $user_rec2"
18215                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18216                 [ -n "$user_rec2" ] ||
18217                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18218                 [ $user_rec1 == $user_rec2 ] ||
18219                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18220                               "$user_rec1, but is $user_rec2"
18221         done
18222
18223         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18224         local sleep2=$((idle_time - (SECONDS - start) + 1))
18225         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18226         sleep $sleep2
18227
18228         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18229         # cl_user1 should be OK because it recently processed records.
18230         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18231         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18232                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18233                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18234         done
18235
18236         # ensure gc thread is done
18237         for i in $(mdts_nodes); do
18238                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18239                         error "$i: GC-thread not done"
18240         done
18241
18242         local first_rec
18243         for (( i = 1; i <= MDSCOUNT; i++ )); do
18244                 # check cl_user1 still registered
18245                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18246                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18247                 # check cl_user2 unregistered
18248                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18249                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18250
18251                 # check changelogs are present and starting at $user_rec1 + 1
18252                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18253                 [ -n "$user_rec1" ] ||
18254                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18255                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18256                             awk '{ print $1; exit; }')
18257
18258                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18259                 [ $((user_rec1 + 1)) == $first_rec ] ||
18260                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18261         done
18262 }
18263 run_test 160f "changelog garbage collect (timestamped users)"
18264
18265 test_160g() {
18266         remote_mds_nodsh && skip "remote MDS with nodsh"
18267         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18268                 skip "Need MDS version at least 2.14.55"
18269
18270         local mdts=$(comma_list $(mdts_nodes))
18271
18272         # Create a user
18273         changelog_register || error "first changelog_register failed"
18274         changelog_register || error "second changelog_register failed"
18275         local cl_users
18276         declare -A cl_user1
18277         declare -A cl_user2
18278         local user_rec1
18279         local user_rec2
18280         local i
18281
18282         # generate some changelog records to accumulate on each MDT
18283         # use all_char because created files should be evenly distributed
18284         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18285                 error "test_mkdir $tdir failed"
18286         for ((i = 0; i < MDSCOUNT; i++)); do
18287                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18288                         error "create $DIR/$tdir/d$i.1 failed"
18289         done
18290
18291         # check changelogs have been generated
18292         local nbcl=$(changelog_dump | wc -l)
18293         (( $nbcl > 0 )) || error "no changelogs found"
18294
18295         # reduce the max_idle_indexes value to make sure we exceed it
18296         for param in "changelog_max_idle_indexes=2" \
18297                      "changelog_gc=1" \
18298                      "changelog_min_gc_interval=2"; do
18299                 local MDT0=$(facet_svc $SINGLEMDS)
18300                 local var="${param%=*}"
18301                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18302
18303                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18304                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18305                         error "unable to set mdd.*.$param"
18306         done
18307
18308         local start=$SECONDS
18309         for i in $(seq $MDSCOUNT); do
18310                 cl_users=(${CL_USERS[mds$i]})
18311                 cl_user1[mds$i]="${cl_users[0]}"
18312                 cl_user2[mds$i]="${cl_users[1]}"
18313
18314                 [ -n "${cl_user1[mds$i]}" ] ||
18315                         error "mds$i: user1 is not registered"
18316                 [ -n "${cl_user2[mds$i]}" ] ||
18317                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18318
18319                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18320                 [ -n "$user_rec1" ] ||
18321                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18322                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18323                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18324                 [ -n "$user_rec2" ] ||
18325                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18326                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18327                      "$user_rec1 + 2 == $user_rec2"
18328                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18329                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18330                               "expected $user_rec1 + 2, but is $user_rec2"
18331                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18332                 [ -n "$user_rec2" ] ||
18333                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18334                 [ $user_rec1 == $user_rec2 ] ||
18335                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18336                               "expected $user_rec1, but is $user_rec2"
18337         done
18338
18339         # ensure we are past the previous changelog_min_gc_interval set above
18340         local sleep2=$((start + 2 - SECONDS))
18341         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18342         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18343         # cl_user1 should be OK because it recently processed records.
18344         for ((i = 0; i < MDSCOUNT; i++)); do
18345                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18346                         error "create $DIR/$tdir/d$i.3 failed"
18347         done
18348
18349         # ensure gc thread is done
18350         for i in $(mdts_nodes); do
18351                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18352                         error "$i: GC-thread not done"
18353         done
18354
18355         local first_rec
18356         for (( i = 1; i <= MDSCOUNT; i++ )); do
18357                 # check cl_user1 still registered
18358                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18359                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18360                 # check cl_user2 unregistered
18361                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18362                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18363
18364                 # check changelogs are present and starting at $user_rec1 + 1
18365                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18366                 [ -n "$user_rec1" ] ||
18367                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18368                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18369                             awk '{ print $1; exit; }')
18370
18371                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18372                 [ $((user_rec1 + 1)) == $first_rec ] ||
18373                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18374         done
18375 }
18376 run_test 160g "changelog garbage collect on idle records"
18377
18378 test_160h() {
18379         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18380         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18381                 skip "Need MDS version at least 2.10.56"
18382
18383         local mdts=$(comma_list $(mdts_nodes))
18384
18385         # Create a user
18386         changelog_register || error "first changelog_register failed"
18387         changelog_register || error "second changelog_register failed"
18388         local cl_users
18389         declare -A cl_user1
18390         declare -A cl_user2
18391         local user_rec1
18392         local user_rec2
18393         local i
18394
18395         # generate some changelog records to accumulate on each MDT
18396         # use all_char because created files should be evenly distributed
18397         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18398                 error "test_mkdir $tdir failed"
18399         for ((i = 0; i < MDSCOUNT; i++)); do
18400                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18401                         error "create $DIR/$tdir/d$i.1 failed"
18402         done
18403
18404         # check changelogs have been generated
18405         local nbcl=$(changelog_dump | wc -l)
18406         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18407
18408         for param in "changelog_max_idle_time=10" \
18409                      "changelog_gc=1" \
18410                      "changelog_min_gc_interval=2"; do
18411                 local MDT0=$(facet_svc $SINGLEMDS)
18412                 local var="${param%=*}"
18413                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18414
18415                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18416                 do_nodes $mdts $LCTL set_param mdd.*.$param
18417         done
18418
18419         # force cl_user2 to be idle (1st part)
18420         sleep 9
18421
18422         for i in $(seq $MDSCOUNT); do
18423                 cl_users=(${CL_USERS[mds$i]})
18424                 cl_user1[mds$i]="${cl_users[0]}"
18425                 cl_user2[mds$i]="${cl_users[1]}"
18426
18427                 [ -n "${cl_user1[mds$i]}" ] ||
18428                         error "mds$i: no user registered"
18429                 [ -n "${cl_user2[mds$i]}" ] ||
18430                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18431
18432                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18433                 [ -n "$user_rec1" ] ||
18434                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18435                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18436                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18437                 [ -n "$user_rec2" ] ||
18438                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18439                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18440                      "$user_rec1 + 2 == $user_rec2"
18441                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18442                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18443                               "$user_rec1 + 2, but is $user_rec2"
18444                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18445                 [ -n "$user_rec2" ] ||
18446                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18447                 [ $user_rec1 == $user_rec2 ] ||
18448                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18449                               "$user_rec1, but is $user_rec2"
18450         done
18451
18452         # force cl_user2 to be idle (2nd part) and to reach
18453         # changelog_max_idle_time
18454         sleep 2
18455
18456         # force each GC-thread start and block then
18457         # one per MDT/MDD, set fail_val accordingly
18458         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18459         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18460
18461         # generate more changelogs to trigger fail_loc
18462         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18463                 error "create $DIR/$tdir/${tfile}bis failed"
18464
18465         # stop MDT to stop GC-thread, should be done in back-ground as it will
18466         # block waiting for the thread to be released and exit
18467         declare -A stop_pids
18468         for i in $(seq $MDSCOUNT); do
18469                 stop mds$i &
18470                 stop_pids[mds$i]=$!
18471         done
18472
18473         for i in $(mdts_nodes); do
18474                 local facet
18475                 local nb=0
18476                 local facets=$(facets_up_on_host $i)
18477
18478                 for facet in ${facets//,/ }; do
18479                         if [[ $facet == mds* ]]; then
18480                                 nb=$((nb + 1))
18481                         fi
18482                 done
18483                 # ensure each MDS's gc threads are still present and all in "R"
18484                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18485                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18486                         error "$i: expected $nb GC-thread"
18487                 wait_update $i \
18488                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18489                         "R" 20 ||
18490                         error "$i: GC-thread not found in R-state"
18491                 # check umounts of each MDT on MDS have reached kthread_stop()
18492                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18493                         error "$i: expected $nb umount"
18494                 wait_update $i \
18495                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18496                         error "$i: umount not found in D-state"
18497         done
18498
18499         # release all GC-threads
18500         do_nodes $mdts $LCTL set_param fail_loc=0
18501
18502         # wait for MDT stop to complete
18503         for i in $(seq $MDSCOUNT); do
18504                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18505         done
18506
18507         # XXX
18508         # may try to check if any orphan changelog records are present
18509         # via ldiskfs/zfs and llog_reader...
18510
18511         # re-start/mount MDTs
18512         for i in $(seq $MDSCOUNT); do
18513                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18514                         error "Fail to start mds$i"
18515         done
18516
18517         local first_rec
18518         for i in $(seq $MDSCOUNT); do
18519                 # check cl_user1 still registered
18520                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18521                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18522                 # check cl_user2 unregistered
18523                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18524                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18525
18526                 # check changelogs are present and starting at $user_rec1 + 1
18527                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18528                 [ -n "$user_rec1" ] ||
18529                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18530                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18531                             awk '{ print $1; exit; }')
18532
18533                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18534                 [ $((user_rec1 + 1)) == $first_rec ] ||
18535                         error "mds$i: first index should be $user_rec1 + 1, " \
18536                               "but is $first_rec"
18537         done
18538 }
18539 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18540               "during mount"
18541
18542 test_160i() {
18543
18544         local mdts=$(comma_list $(mdts_nodes))
18545
18546         changelog_register || error "first changelog_register failed"
18547
18548         # generate some changelog records to accumulate on each MDT
18549         # use all_char because created files should be evenly distributed
18550         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18551                 error "test_mkdir $tdir failed"
18552         for ((i = 0; i < MDSCOUNT; i++)); do
18553                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18554                         error "create $DIR/$tdir/d$i.1 failed"
18555         done
18556
18557         # check changelogs have been generated
18558         local nbcl=$(changelog_dump | wc -l)
18559         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18560
18561         # simulate race between register and unregister
18562         # XXX as fail_loc is set per-MDS, with DNE configs the race
18563         # simulation will only occur for one MDT per MDS and for the
18564         # others the normal race scenario will take place
18565         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18566         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18567         do_nodes $mdts $LCTL set_param fail_val=1
18568
18569         # unregister 1st user
18570         changelog_deregister &
18571         local pid1=$!
18572         # wait some time for deregister work to reach race rdv
18573         sleep 2
18574         # register 2nd user
18575         changelog_register || error "2nd user register failed"
18576
18577         wait $pid1 || error "1st user deregister failed"
18578
18579         local i
18580         local last_rec
18581         declare -A LAST_REC
18582         for i in $(seq $MDSCOUNT); do
18583                 if changelog_users mds$i | grep "^cl"; then
18584                         # make sure new records are added with one user present
18585                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18586                                           awk '/^current.index:/ { print $NF }')
18587                 else
18588                         error "mds$i has no user registered"
18589                 fi
18590         done
18591
18592         # generate more changelog records to accumulate on each MDT
18593         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18594                 error "create $DIR/$tdir/${tfile}bis failed"
18595
18596         for i in $(seq $MDSCOUNT); do
18597                 last_rec=$(changelog_users $SINGLEMDS |
18598                            awk '/^current.index:/ { print $NF }')
18599                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18600                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18601                         error "changelogs are off on mds$i"
18602         done
18603 }
18604 run_test 160i "changelog user register/unregister race"
18605
18606 test_160j() {
18607         remote_mds_nodsh && skip "remote MDS with nodsh"
18608         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18609                 skip "Need MDS version at least 2.12.56"
18610
18611         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18612         stack_trap "umount $MOUNT2" EXIT
18613
18614         changelog_register || error "first changelog_register failed"
18615         stack_trap "changelog_deregister" EXIT
18616
18617         # generate some changelog
18618         # use all_char because created files should be evenly distributed
18619         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18620                 error "mkdir $tdir failed"
18621         for ((i = 0; i < MDSCOUNT; i++)); do
18622                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18623                         error "create $DIR/$tdir/d$i.1 failed"
18624         done
18625
18626         # open the changelog device
18627         exec 3>/dev/changelog-$FSNAME-MDT0000
18628         stack_trap "exec 3>&-" EXIT
18629         exec 4</dev/changelog-$FSNAME-MDT0000
18630         stack_trap "exec 4<&-" EXIT
18631
18632         # umount the first lustre mount
18633         umount $MOUNT
18634         stack_trap "mount_client $MOUNT" EXIT
18635
18636         # read changelog, which may or may not fail, but should not crash
18637         cat <&4 >/dev/null
18638
18639         # clear changelog
18640         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18641         changelog_users $SINGLEMDS | grep -q $cl_user ||
18642                 error "User $cl_user not found in changelog_users"
18643
18644         printf 'clear:'$cl_user':0' >&3
18645 }
18646 run_test 160j "client can be umounted while its chanangelog is being used"
18647
18648 test_160k() {
18649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18650         remote_mds_nodsh && skip "remote MDS with nodsh"
18651
18652         mkdir -p $DIR/$tdir/1/1
18653
18654         changelog_register || error "changelog_register failed"
18655         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18656
18657         changelog_users $SINGLEMDS | grep -q $cl_user ||
18658                 error "User '$cl_user' not found in changelog_users"
18659 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18660         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18661         rmdir $DIR/$tdir/1/1 & sleep 1
18662         mkdir $DIR/$tdir/2
18663         touch $DIR/$tdir/2/2
18664         rm -rf $DIR/$tdir/2
18665
18666         wait
18667         sleep 4
18668
18669         changelog_dump | grep rmdir || error "rmdir not recorded"
18670 }
18671 run_test 160k "Verify that changelog records are not lost"
18672
18673 # Verifies that a file passed as a parameter has recently had an operation
18674 # performed on it that has generated an MTIME changelog which contains the
18675 # correct parent FID. As files might reside on a different MDT from the
18676 # parent directory in DNE configurations, the FIDs are translated to paths
18677 # before being compared, which should be identical
18678 compare_mtime_changelog() {
18679         local file="${1}"
18680         local mdtidx
18681         local mtime
18682         local cl_fid
18683         local pdir
18684         local dir
18685
18686         mdtidx=$($LFS getstripe --mdt-index $file)
18687         mdtidx=$(printf "%04x" $mdtidx)
18688
18689         # Obtain the parent FID from the MTIME changelog
18690         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18691         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18692
18693         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18694         [ -z "$cl_fid" ] && error "parent FID not present"
18695
18696         # Verify that the path for the parent FID is the same as the path for
18697         # the test directory
18698         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18699
18700         dir=$(dirname $1)
18701
18702         [[ "${pdir%/}" == "$dir" ]] ||
18703                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18704 }
18705
18706 test_160l() {
18707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18708
18709         remote_mds_nodsh && skip "remote MDS with nodsh"
18710         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18711                 skip "Need MDS version at least 2.13.55"
18712
18713         local cl_user
18714
18715         changelog_register || error "changelog_register failed"
18716         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18717
18718         changelog_users $SINGLEMDS | grep -q $cl_user ||
18719                 error "User '$cl_user' not found in changelog_users"
18720
18721         # Clear some types so that MTIME changelogs are generated
18722         changelog_chmask "-CREAT"
18723         changelog_chmask "-CLOSE"
18724
18725         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18726
18727         # Test CL_MTIME during setattr
18728         touch $DIR/$tdir/$tfile
18729         compare_mtime_changelog $DIR/$tdir/$tfile
18730
18731         # Test CL_MTIME during close
18732         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18733         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18734 }
18735 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18736
18737 test_160m() {
18738         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18739         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18740                 skip "Need MDS version at least 2.14.51"
18741         local cl_users
18742         local cl_user1
18743         local cl_user2
18744         local pid1
18745
18746         # Create a user
18747         changelog_register || error "first changelog_register failed"
18748         changelog_register || error "second changelog_register failed"
18749
18750         cl_users=(${CL_USERS[mds1]})
18751         cl_user1="${cl_users[0]}"
18752         cl_user2="${cl_users[1]}"
18753         # generate some changelog records to accumulate on MDT0
18754         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18755         createmany -m $DIR/$tdir/$tfile 50 ||
18756                 error "create $DIR/$tdir/$tfile failed"
18757         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18758         rm -f $DIR/$tdir
18759
18760         # check changelogs have been generated
18761         local nbcl=$(changelog_dump | wc -l)
18762         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18763
18764 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18765         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18766
18767         __changelog_clear mds1 $cl_user1 +10
18768         __changelog_clear mds1 $cl_user2 0 &
18769         pid1=$!
18770         sleep 2
18771         __changelog_clear mds1 $cl_user1 0 ||
18772                 error "fail to cancel record for $cl_user1"
18773         wait $pid1
18774         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18775 }
18776 run_test 160m "Changelog clear race"
18777
18778 test_160n() {
18779         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18780         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18781                 skip "Need MDS version at least 2.14.51"
18782         local cl_users
18783         local cl_user1
18784         local pid1
18785         local first_rec
18786         local last_rec=0
18787
18788         # Create a user
18789         changelog_register || error "first changelog_register failed"
18790
18791         cl_users=(${CL_USERS[mds1]})
18792         cl_user1="${cl_users[0]}"
18793
18794         # generate some changelog records to accumulate on MDT0
18795         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18796         first_rec=$(changelog_users $SINGLEMDS |
18797                         awk '/^current.index:/ { print $NF }')
18798         while (( last_rec < (( first_rec + 65000)) )); do
18799                 createmany -m $DIR/$tdir/$tfile 10000 ||
18800                         error "create $DIR/$tdir/$tfile failed"
18801
18802                 for i in $(seq 0 10000); do
18803                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18804                                 > /dev/null
18805                 done
18806
18807                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18808                         error "unlinkmany failed unlink"
18809                 last_rec=$(changelog_users $SINGLEMDS |
18810                         awk '/^current.index:/ { print $NF }')
18811                 echo last record $last_rec
18812                 (( last_rec == 0 )) && error "no changelog found"
18813         done
18814
18815 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18816         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18817
18818         __changelog_clear mds1 $cl_user1 0 &
18819         pid1=$!
18820         sleep 2
18821         __changelog_clear mds1 $cl_user1 0 ||
18822                 error "fail to cancel record for $cl_user1 (forground)"
18823         wait $pid1
18824         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user1 (background)"
18825 }
18826 run_test 160n "Changelog destroy race"
18827
18828 test_160o() {
18829         local mdt="$(facet_svc $SINGLEMDS)"
18830
18831         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18832         remote_mds_nodsh && skip "remote MDS with nodsh"
18833         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18834                 skip "Need MDS version at least 2.14.52"
18835
18836         changelog_register --user test_160o -m unlnk+close+open ||
18837                 error "changelog_register failed"
18838
18839         do_facet $SINGLEMDS $LCTL --device $mdt \
18840                                 changelog_register -u "Tt3_-#" &&
18841                 error "bad symbols in name should fail"
18842
18843         do_facet $SINGLEMDS $LCTL --device $mdt \
18844                                 changelog_register -u test_160o &&
18845                 error "the same name registration should fail"
18846
18847         do_facet $SINGLEMDS $LCTL --device $mdt \
18848                         changelog_register -u test_160toolongname &&
18849                 error "too long name registration should fail"
18850
18851         changelog_chmask "MARK+HSM"
18852         lctl get_param mdd.*.changelog*mask
18853         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18854         changelog_users $SINGLEMDS | grep -q $cl_user ||
18855                 error "User $cl_user not found in changelog_users"
18856         #verify username
18857         echo $cl_user | grep -q test_160o ||
18858                 error "User $cl_user has no specific name 'test160o'"
18859
18860         # change something
18861         changelog_clear 0 || error "changelog_clear failed"
18862         # generate some changelog records to accumulate on MDT0
18863         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18864         touch $DIR/$tdir/$tfile                 # open 1
18865
18866         OPENS=$(changelog_dump | grep -c "OPEN")
18867         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18868
18869         # must be no MKDIR it wasn't set as user mask
18870         MKDIR=$(changelog_dump | grep -c "MKDIR")
18871         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18872
18873         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18874                                 mdd.$mdt.changelog_current_mask -n)
18875         # register maskless user
18876         changelog_register || error "changelog_register failed"
18877         # effective mask should be not changed because it is not minimal
18878         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18879                                 mdd.$mdt.changelog_current_mask -n)
18880         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18881         # set server mask to minimal value
18882         changelog_chmask "MARK"
18883         # check effective mask again, should be treated as DEFMASK now
18884         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18885                                 mdd.$mdt.changelog_current_mask -n)
18886         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18887
18888         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18889                 # set server mask back to some value
18890                 changelog_chmask "CLOSE,UNLNK"
18891                 # check effective mask again, should not remain as DEFMASK
18892                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18893                                 mdd.$mdt.changelog_current_mask -n)
18894                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18895         fi
18896
18897         do_facet $SINGLEMDS $LCTL --device $mdt \
18898                                 changelog_deregister -u test_160o ||
18899                 error "cannot deregister by name"
18900 }
18901 run_test 160o "changelog user name and mask"
18902
18903 test_160p() {
18904         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18905         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18906                 skip "Need MDS version at least 2.14.51"
18907         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18908         local cl_users
18909         local cl_user1
18910         local entry_count
18911
18912         # Create a user
18913         changelog_register || error "first changelog_register failed"
18914
18915         cl_users=(${CL_USERS[mds1]})
18916         cl_user1="${cl_users[0]}"
18917
18918         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18919         createmany -m $DIR/$tdir/$tfile 50 ||
18920                 error "create $DIR/$tdir/$tfile failed"
18921         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18922         rm -rf $DIR/$tdir
18923
18924         # check changelogs have been generated
18925         entry_count=$(changelog_dump | wc -l)
18926         ((entry_count != 0)) || error "no changelog entries found"
18927
18928         # remove changelog_users and check that orphan entries are removed
18929         stop mds1
18930         local dev=$(mdsdevname 1)
18931         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18932         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18933         entry_count=$(changelog_dump | wc -l)
18934         ((entry_count == 0)) ||
18935                 error "found $entry_count changelog entries, expected none"
18936 }
18937 run_test 160p "Changelog orphan cleanup with no users"
18938
18939 test_160q() {
18940         local mdt="$(facet_svc $SINGLEMDS)"
18941         local clu
18942
18943         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18944         remote_mds_nodsh && skip "remote MDS with nodsh"
18945         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18946                 skip "Need MDS version at least 2.14.54"
18947
18948         # set server mask to minimal value like server init does
18949         changelog_chmask "MARK"
18950         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18951                 error "changelog_register failed"
18952         # check effective mask again, should be treated as DEFMASK now
18953         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18954                                 mdd.$mdt.changelog_current_mask -n)
18955         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18956                 error "changelog_deregister failed"
18957         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18958 }
18959 run_test 160q "changelog effective mask is DEFMASK if not set"
18960
18961 test_160s() {
18962         remote_mds_nodsh && skip "remote MDS with nodsh"
18963         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18964                 skip "Need MDS version at least 2.14.55"
18965
18966         local mdts=$(comma_list $(mdts_nodes))
18967
18968         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18969         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18970                                        fail_val=$((24 * 3600 * 10))
18971
18972         # Create a user which is 10 days old
18973         changelog_register || error "first changelog_register failed"
18974         local cl_users
18975         declare -A cl_user1
18976         local i
18977
18978         # generate some changelog records to accumulate on each MDT
18979         # use all_char because created files should be evenly distributed
18980         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18981                 error "test_mkdir $tdir failed"
18982         for ((i = 0; i < MDSCOUNT; i++)); do
18983                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18984                         error "create $DIR/$tdir/d$i.1 failed"
18985         done
18986
18987         # check changelogs have been generated
18988         local nbcl=$(changelog_dump | wc -l)
18989         (( nbcl > 0 )) || error "no changelogs found"
18990
18991         # reduce the max_idle_indexes value to make sure we exceed it
18992         for param in "changelog_max_idle_indexes=2097446912" \
18993                      "changelog_max_idle_time=2592000" \
18994                      "changelog_gc=1" \
18995                      "changelog_min_gc_interval=2"; do
18996                 local MDT0=$(facet_svc $SINGLEMDS)
18997                 local var="${param%=*}"
18998                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18999
19000                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
19001                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
19002                         error "unable to set mdd.*.$param"
19003         done
19004
19005         local start=$SECONDS
19006         for i in $(seq $MDSCOUNT); do
19007                 cl_users=(${CL_USERS[mds$i]})
19008                 cl_user1[mds$i]="${cl_users[0]}"
19009
19010                 [[ -n "${cl_user1[mds$i]}" ]] ||
19011                         error "mds$i: no user registered"
19012         done
19013
19014         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
19015         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
19016
19017         # ensure we are past the previous changelog_min_gc_interval set above
19018         local sleep2=$((start + 2 - SECONDS))
19019         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
19020
19021         # Generate one more changelog to trigger GC
19022         for ((i = 0; i < MDSCOUNT; i++)); do
19023                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
19024                         error "create $DIR/$tdir/d$i.3 failed"
19025         done
19026
19027         # ensure gc thread is done
19028         for node in $(mdts_nodes); do
19029                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
19030                         error "$node: GC-thread not done"
19031         done
19032
19033         do_nodes $mdts $LCTL set_param fail_loc=0
19034
19035         for (( i = 1; i <= MDSCOUNT; i++ )); do
19036                 # check cl_user1 is purged
19037                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
19038                         error "mds$i: User ${cl_user1[mds$i]} is registered"
19039         done
19040         return 0
19041 }
19042 run_test 160s "changelog garbage collect on idle records * time"
19043
19044 test_160t() {
19045         remote_mds_nodsh && skip "remote MDS with nodsh"
19046         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
19047                 skip "Need MDS version at least 2.15.50"
19048
19049         local MDT0=$(facet_svc $SINGLEMDS)
19050         local cl_users
19051         local cl_user1
19052         local cl_user2
19053         local start
19054
19055         changelog_register --user user1 -m all ||
19056                 error "user1 failed to register"
19057
19058         mkdir_on_mdt0 $DIR/$tdir
19059         # create default overstripe to maximize changelog size
19060         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
19061         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
19062         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
19063
19064         # user2 consumes less records so less space
19065         changelog_register --user user2 || error "user2 failed to register"
19066         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
19067         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
19068
19069         # check changelogs have been generated
19070         local nbcl=$(changelog_dump | wc -l)
19071         (( nbcl > 0 )) || error "no changelogs found"
19072
19073         # reduce the changelog_min_gc_interval to force check
19074         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
19075                 local var="${param%=*}"
19076                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
19077
19078                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
19079                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
19080                         error "unable to set mdd.*.$param"
19081         done
19082
19083         start=$SECONDS
19084         cl_users=(${CL_USERS[mds1]})
19085         cl_user1="${cl_users[0]}"
19086         cl_user2="${cl_users[1]}"
19087
19088         [[ -n $cl_user1 ]] ||
19089                 error "mds1: user #1 isn't registered"
19090         [[ -n $cl_user2 ]] ||
19091                 error "mds1: user #2 isn't registered"
19092
19093         # ensure we are past the previous changelog_min_gc_interval set above
19094         local sleep2=$((start + 2 - SECONDS))
19095         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
19096
19097         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
19098         do_facet mds1 $LCTL set_param fail_loc=0x018c \
19099                         fail_val=$(((llog_size1 + llog_size2) / 2))
19100
19101         # Generate more changelog to trigger GC
19102         createmany -o $DIR/$tdir/u3_ 4 ||
19103                 error "create failed for more files"
19104
19105         # ensure gc thread is done
19106         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
19107                 error "mds1: GC-thread not done"
19108
19109         do_facet mds1 $LCTL set_param fail_loc=0
19110
19111         # check cl_user1 is purged
19112         changelog_users mds1 | grep -q "$cl_user1" &&
19113                 error "User $cl_user1 is registered"
19114         # check cl_user2 is not purged
19115         changelog_users mds1 | grep -q "$cl_user2" ||
19116                 error "User $cl_user2 is not registered"
19117 }
19118 run_test 160t "changelog garbage collect on lack of space"
19119
19120 test_160u() { # LU-17400
19121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19122         remote_mds_nodsh && skip "remote MDS with nodsh"
19123         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
19124                 skip "Need MDS version at least 2.2.0"
19125
19126         cd $DIR || error "cd $DIR failed"
19127
19128         # ensure changelog has a clean view if tests are run multiple times
19129         [ -d rename ] && rm -rf rename
19130
19131         changelog_register || error "changelog_register failed"
19132         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
19133
19134         changelog_users $SINGLEMDS | grep -q $cl_user ||
19135                 error "User '$cl_user' not found in changelog_users"
19136
19137         local longname1=$(str_repeat a 255)
19138
19139         echo "creating simple directory tree"
19140         mkdir -p rename/a || error "create of simple directory tree failed"
19141         echo "creating rename/hw file"
19142         echo "hello world" > rename/hw || error "create of rename/hw failed"
19143         echo "creating very long named file"
19144         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
19145         echo "move rename/hw to rename/a/a.hw"
19146         mv rename/hw rename/a/a.hw || error "mv failed"
19147
19148         RENME=($(changelog_dump | grep "RENME"))
19149         #declare -p RENME # for debugging captured value with indexes
19150
19151         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
19152                 error "changelog rename record type name/sname error"
19153 }
19154 run_test 160u "changelog rename record type name and sname strings are correct"
19155
19156 test_161a() {
19157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19158
19159         test_mkdir -c1 $DIR/$tdir
19160         cp /etc/hosts $DIR/$tdir/$tfile
19161         test_mkdir -c1 $DIR/$tdir/foo1
19162         test_mkdir -c1 $DIR/$tdir/foo2
19163         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
19164         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
19165         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
19166         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
19167         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
19168         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19169                 $LFS fid2path $DIR $FID
19170                 error "bad link ea"
19171         fi
19172         # middle
19173         rm $DIR/$tdir/foo2/zachary
19174         # last
19175         rm $DIR/$tdir/foo2/thor
19176         # first
19177         rm $DIR/$tdir/$tfile
19178         # rename
19179         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
19180         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
19181                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
19182         rm $DIR/$tdir/foo2/maggie
19183
19184         # overflow the EA
19185         local longname=$tfile.avg_len_is_thirty_two_
19186         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
19187                 error_noexit 'failed to unlink many hardlinks'" EXIT
19188         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
19189                 error "failed to hardlink many files"
19190         links=$($LFS fid2path $DIR $FID | wc -l)
19191         echo -n "${links}/1000 links in link EA"
19192         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
19193 }
19194 run_test 161a "link ea sanity"
19195
19196 test_161b() {
19197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19198         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
19199
19200         local MDTIDX=1
19201         local remote_dir=$DIR/$tdir/remote_dir
19202
19203         mkdir -p $DIR/$tdir
19204         $LFS mkdir -i $MDTIDX $remote_dir ||
19205                 error "create remote directory failed"
19206
19207         cp /etc/hosts $remote_dir/$tfile
19208         mkdir -p $remote_dir/foo1
19209         mkdir -p $remote_dir/foo2
19210         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19211         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19212         ln $remote_dir/$tfile $remote_dir/foo1/luna
19213         ln $remote_dir/$tfile $remote_dir/foo2/thor
19214
19215         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19216                      tr -d ']')
19217         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19218                 $LFS fid2path $DIR $FID
19219                 error "bad link ea"
19220         fi
19221         # middle
19222         rm $remote_dir/foo2/zachary
19223         # last
19224         rm $remote_dir/foo2/thor
19225         # first
19226         rm $remote_dir/$tfile
19227         # rename
19228         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19229         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19230         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19231                 $LFS fid2path $DIR $FID
19232                 error "bad link rename"
19233         fi
19234         rm $remote_dir/foo2/maggie
19235
19236         # overflow the EA
19237         local longname=filename_avg_len_is_thirty_two_
19238         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19239                 error "failed to hardlink many files"
19240         links=$($LFS fid2path $DIR $FID | wc -l)
19241         echo -n "${links}/1000 links in link EA"
19242         [[ ${links} -gt 60 ]] ||
19243                 error "expected at least 60 links in link EA"
19244         unlinkmany $remote_dir/foo2/$longname 1000 ||
19245         error "failed to unlink many hardlinks"
19246 }
19247 run_test 161b "link ea sanity under remote directory"
19248
19249 test_161c() {
19250         remote_mds_nodsh && skip "remote MDS with nodsh"
19251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19252         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19253                 skip "Need MDS version at least 2.1.5"
19254
19255         # define CLF_RENAME_LAST 0x0001
19256         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19257         changelog_register || error "changelog_register failed"
19258
19259         rm -rf $DIR/$tdir
19260         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19261         touch $DIR/$tdir/foo_161c
19262         touch $DIR/$tdir/bar_161c
19263         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19264         changelog_dump | grep RENME | tail -n 5
19265         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19266         changelog_clear 0 || error "changelog_clear failed"
19267         if [ x$flags != "x0x1" ]; then
19268                 error "flag $flags is not 0x1"
19269         fi
19270
19271         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19272         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19273         touch $DIR/$tdir/foo_161c
19274         touch $DIR/$tdir/bar_161c
19275         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19276         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19277         changelog_dump | grep RENME | tail -n 5
19278         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19279         changelog_clear 0 || error "changelog_clear failed"
19280         if [ x$flags != "x0x0" ]; then
19281                 error "flag $flags is not 0x0"
19282         fi
19283         echo "rename overwrite a target having nlink > 1," \
19284                 "changelog record has flags of $flags"
19285
19286         # rename doesn't overwrite a target (changelog flag 0x0)
19287         touch $DIR/$tdir/foo_161c
19288         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19289         changelog_dump | grep RENME | tail -n 5
19290         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19291         changelog_clear 0 || error "changelog_clear failed"
19292         if [ x$flags != "x0x0" ]; then
19293                 error "flag $flags is not 0x0"
19294         fi
19295         echo "rename doesn't overwrite a target," \
19296                 "changelog record has flags of $flags"
19297
19298         # define CLF_UNLINK_LAST 0x0001
19299         # unlink a file having nlink = 1 (changelog flag 0x1)
19300         rm -f $DIR/$tdir/foo2_161c
19301         changelog_dump | grep UNLNK | tail -n 5
19302         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19303         changelog_clear 0 || error "changelog_clear failed"
19304         if [ x$flags != "x0x1" ]; then
19305                 error "flag $flags is not 0x1"
19306         fi
19307         echo "unlink a file having nlink = 1," \
19308                 "changelog record has flags of $flags"
19309
19310         # unlink a file having nlink > 1 (changelog flag 0x0)
19311         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19312         rm -f $DIR/$tdir/foobar_161c
19313         changelog_dump | grep UNLNK | tail -n 5
19314         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19315         changelog_clear 0 || error "changelog_clear failed"
19316         if [ x$flags != "x0x0" ]; then
19317                 error "flag $flags is not 0x0"
19318         fi
19319         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19320 }
19321 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19322
19323 test_161d() {
19324         remote_mds_nodsh && skip "remote MDS with nodsh"
19325         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19326
19327         local pid
19328         local fid
19329
19330         changelog_register || error "changelog_register failed"
19331
19332         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19333         # interfer with $MOUNT/.lustre/fid/ access
19334         mkdir $DIR/$tdir
19335         [[ $? -eq 0 ]] || error "mkdir failed"
19336
19337         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19338         $LCTL set_param fail_loc=0x8000140c
19339         # 5s pause
19340         $LCTL set_param fail_val=5
19341
19342         # create file
19343         echo foofoo > $DIR/$tdir/$tfile &
19344         pid=$!
19345
19346         # wait for create to be delayed
19347         sleep 2
19348
19349         ps -p $pid
19350         [[ $? -eq 0 ]] || error "create should be blocked"
19351
19352         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19353         stack_trap "rm -f $tempfile"
19354         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19355         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19356         # some delay may occur during ChangeLog publishing and file read just
19357         # above, that could allow file write to happen finally
19358         [[ -s $tempfile ]] && echo "file should be empty"
19359
19360         $LCTL set_param fail_loc=0
19361
19362         wait $pid
19363         [[ $? -eq 0 ]] || error "create failed"
19364 }
19365 run_test 161d "create with concurrent .lustre/fid access"
19366
19367 check_path() {
19368         local expected="$1"
19369         shift
19370         local fid="$2"
19371
19372         local path
19373         path=$($LFS fid2path "$@")
19374         local rc=$?
19375
19376         if [ $rc -ne 0 ]; then
19377                 error "path looked up of '$expected' failed: rc=$rc"
19378         elif [ "$path" != "$expected" ]; then
19379                 error "path looked up '$path' instead of '$expected'"
19380         else
19381                 echo "FID '$fid' resolves to path '$path' as expected"
19382         fi
19383 }
19384
19385 test_162a() { # was test_162
19386         test_mkdir -p -c1 $DIR/$tdir/d2
19387         touch $DIR/$tdir/d2/$tfile
19388         touch $DIR/$tdir/d2/x1
19389         touch $DIR/$tdir/d2/x2
19390         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19391         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19392         # regular file
19393         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19394         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19395
19396         # softlink
19397         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19398         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19399         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19400
19401         # softlink to wrong file
19402         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19403         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19404         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19405
19406         # hardlink
19407         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19408         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19409         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19410         # fid2path dir/fsname should both work
19411         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19412         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19413
19414         # hardlink count: check that there are 2 links
19415         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19416         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19417
19418         # hardlink indexing: remove the first link
19419         rm $DIR/$tdir/d2/p/q/r/hlink
19420         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19421 }
19422 run_test 162a "path lookup sanity"
19423
19424 test_162b() {
19425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19426         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19427
19428         mkdir $DIR/$tdir
19429         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19430                                 error "create striped dir failed"
19431
19432         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19433                                         tail -n 1 | awk '{print $2}')
19434         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19435
19436         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19437         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19438
19439         # regular file
19440         for ((i=0;i<5;i++)); do
19441                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19442                         error "get fid for f$i failed"
19443                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19444
19445                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19446                         error "get fid for d$i failed"
19447                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19448         done
19449
19450         return 0
19451 }
19452 run_test 162b "striped directory path lookup sanity"
19453
19454 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19455 test_162c() {
19456         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19457                 skip "Need MDS version at least 2.7.51"
19458
19459         local lpath=$tdir.local
19460         local rpath=$tdir.remote
19461
19462         test_mkdir $DIR/$lpath
19463         test_mkdir $DIR/$rpath
19464
19465         for ((i = 0; i <= 101; i++)); do
19466                 lpath="$lpath/$i"
19467                 mkdir $DIR/$lpath
19468                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19469                         error "get fid for local directory $DIR/$lpath failed"
19470                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19471
19472                 rpath="$rpath/$i"
19473                 test_mkdir $DIR/$rpath
19474                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19475                         error "get fid for remote directory $DIR/$rpath failed"
19476                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19477         done
19478
19479         return 0
19480 }
19481 run_test 162c "fid2path works with paths 100 or more directories deep"
19482
19483 oalr_event_count() {
19484         local event="${1}"
19485         local trace="${2}"
19486
19487         awk -v name="${FSNAME}-OST0000" \
19488             -v event="${event}" \
19489             '$1 == "TRACE" && $2 == event && $3 == name' \
19490             "${trace}" |
19491         wc -l
19492 }
19493
19494 oalr_expect_event_count() {
19495         local event="${1}"
19496         local trace="${2}"
19497         local expect="${3}"
19498         local count
19499
19500         count=$(oalr_event_count "${event}" "${trace}")
19501         if ((count == expect)); then
19502                 return 0
19503         fi
19504
19505         error_noexit "${event} event count was '${count}', expected ${expect}"
19506         cat "${trace}" >&2
19507         exit 1
19508 }
19509
19510 cleanup_165() {
19511         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19512         stop ost1
19513         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19514 }
19515
19516 setup_165() {
19517         sync # Flush previous IOs so we can count log entries.
19518         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19519         stack_trap cleanup_165 EXIT
19520 }
19521
19522 test_165a() {
19523         local trace="/tmp/${tfile}.trace"
19524         local rc
19525         local count
19526
19527         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19528                 skip "OFD access log unsupported"
19529
19530         setup_165
19531         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19532         sleep 5
19533
19534         do_facet ost1 ofd_access_log_reader --list
19535         stop ost1
19536
19537         do_facet ost1 killall -TERM ofd_access_log_reader
19538         wait
19539         rc=$?
19540
19541         if ((rc != 0)); then
19542                 error "ofd_access_log_reader exited with rc = '${rc}'"
19543         fi
19544
19545         # Parse trace file for discovery events:
19546         oalr_expect_event_count alr_log_add "${trace}" 1
19547         oalr_expect_event_count alr_log_eof "${trace}" 1
19548         oalr_expect_event_count alr_log_free "${trace}" 1
19549 }
19550 run_test 165a "ofd access log discovery"
19551
19552 test_165b() {
19553         local trace="/tmp/${tfile}.trace"
19554         local file="${DIR}/${tfile}"
19555         local pfid1
19556         local pfid2
19557         local -a entry
19558         local rc
19559         local count
19560         local size
19561         local flags
19562
19563         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19564                 skip "OFD access log unsupported"
19565
19566         setup_165
19567         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19568         sleep 5
19569
19570         do_facet ost1 ofd_access_log_reader --list
19571
19572         lfs setstripe -c 1 -i 0 "${file}"
19573         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19574                 error "cannot create '${file}'"
19575
19576         sleep 5
19577         do_facet ost1 killall -TERM ofd_access_log_reader
19578         wait
19579         rc=$?
19580
19581         if ((rc != 0)); then
19582                 error "ofd_access_log_reader exited with rc = '${rc}'"
19583         fi
19584
19585         oalr_expect_event_count alr_log_entry "${trace}" 1
19586
19587         pfid1=$($LFS path2fid "${file}")
19588
19589         # 1     2             3   4    5     6   7    8    9     10
19590         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19591         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19592
19593         echo "entry = '${entry[*]}'" >&2
19594
19595         pfid2=${entry[4]}
19596         if [[ "${pfid1}" != "${pfid2}" ]]; then
19597                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19598         fi
19599
19600         size=${entry[8]}
19601         if ((size != 1048576)); then
19602                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19603         fi
19604
19605         flags=${entry[10]}
19606         if [[ "${flags}" != "w" ]]; then
19607                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19608         fi
19609
19610         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19611         sleep 5
19612
19613         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19614                 error "cannot read '${file}'"
19615         sleep 5
19616
19617         do_facet ost1 killall -TERM ofd_access_log_reader
19618         wait
19619         rc=$?
19620
19621         if ((rc != 0)); then
19622                 error "ofd_access_log_reader exited with rc = '${rc}'"
19623         fi
19624
19625         oalr_expect_event_count alr_log_entry "${trace}" 1
19626
19627         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19628         echo "entry = '${entry[*]}'" >&2
19629
19630         pfid2=${entry[4]}
19631         if [[ "${pfid1}" != "${pfid2}" ]]; then
19632                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19633         fi
19634
19635         size=${entry[8]}
19636         if ((size != 524288)); then
19637                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19638         fi
19639
19640         flags=${entry[10]}
19641         if [[ "${flags}" != "r" ]]; then
19642                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19643         fi
19644 }
19645 run_test 165b "ofd access log entries are produced and consumed"
19646
19647 test_165c() {
19648         local trace="/tmp/${tfile}.trace"
19649         local file="${DIR}/${tdir}/${tfile}"
19650
19651         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19652                 skip "OFD access log unsupported"
19653
19654         test_mkdir "${DIR}/${tdir}"
19655
19656         setup_165
19657         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19658         sleep 5
19659
19660         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19661
19662         # 4096 / 64 = 64. Create twice as many entries.
19663         for ((i = 0; i < 128; i++)); do
19664                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19665                         error "cannot create file"
19666         done
19667
19668         sync
19669
19670         do_facet ost1 killall -TERM ofd_access_log_reader
19671         wait
19672         rc=$?
19673         if ((rc != 0)); then
19674                 error "ofd_access_log_reader exited with rc = '${rc}'"
19675         fi
19676
19677         unlinkmany  "${file}-%d" 128
19678 }
19679 run_test 165c "full ofd access logs do not block IOs"
19680
19681 oal_get_read_count() {
19682         local stats="$1"
19683
19684         # STATS lustre-OST0001 alr_read_count 1
19685
19686         do_facet ost1 cat "${stats}" |
19687         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19688              END { print count; }'
19689 }
19690
19691 oal_expect_read_count() {
19692         local stats="$1"
19693         local count
19694         local expect="$2"
19695
19696         # Ask ofd_access_log_reader to write stats.
19697         do_facet ost1 killall -USR1 ofd_access_log_reader
19698
19699         # Allow some time for things to happen.
19700         sleep 1
19701
19702         count=$(oal_get_read_count "${stats}")
19703         if ((count == expect)); then
19704                 return 0
19705         fi
19706
19707         error_noexit "bad read count, got ${count}, expected ${expect}"
19708         do_facet ost1 cat "${stats}" >&2
19709         exit 1
19710 }
19711
19712 test_165d() {
19713         local stats="/tmp/${tfile}.stats"
19714         local file="${DIR}/${tdir}/${tfile}"
19715         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19716
19717         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19718                 skip "OFD access log unsupported"
19719
19720         test_mkdir "${DIR}/${tdir}"
19721
19722         setup_165
19723         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19724         sleep 5
19725
19726         lfs setstripe -c 1 -i 0 "${file}"
19727
19728         do_facet ost1 lctl set_param "${param}=rw"
19729         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19730                 error "cannot create '${file}'"
19731         oal_expect_read_count "${stats}" 1
19732
19733         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19734                 error "cannot read '${file}'"
19735         oal_expect_read_count "${stats}" 2
19736
19737         do_facet ost1 lctl set_param "${param}=r"
19738         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19739                 error "cannot create '${file}'"
19740         oal_expect_read_count "${stats}" 2
19741
19742         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19743                 error "cannot read '${file}'"
19744         oal_expect_read_count "${stats}" 3
19745
19746         do_facet ost1 lctl set_param "${param}=w"
19747         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19748                 error "cannot create '${file}'"
19749         oal_expect_read_count "${stats}" 4
19750
19751         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19752                 error "cannot read '${file}'"
19753         oal_expect_read_count "${stats}" 4
19754
19755         do_facet ost1 lctl set_param "${param}=0"
19756         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19757                 error "cannot create '${file}'"
19758         oal_expect_read_count "${stats}" 4
19759
19760         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19761                 error "cannot read '${file}'"
19762         oal_expect_read_count "${stats}" 4
19763
19764         do_facet ost1 killall -TERM ofd_access_log_reader
19765         wait
19766         rc=$?
19767         if ((rc != 0)); then
19768                 error "ofd_access_log_reader exited with rc = '${rc}'"
19769         fi
19770 }
19771 run_test 165d "ofd_access_log mask works"
19772
19773 test_165e() {
19774         local stats="/tmp/${tfile}.stats"
19775         local file0="${DIR}/${tdir}-0/${tfile}"
19776         local file1="${DIR}/${tdir}-1/${tfile}"
19777
19778         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19779                 skip "OFD access log unsupported"
19780
19781         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19782
19783         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19784         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19785
19786         lfs setstripe -c 1 -i 0 "${file0}"
19787         lfs setstripe -c 1 -i 0 "${file1}"
19788
19789         setup_165
19790         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19791         sleep 5
19792
19793         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19794                 error "cannot create '${file0}'"
19795         sync
19796         oal_expect_read_count "${stats}" 0
19797
19798         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19799                 error "cannot create '${file1}'"
19800         sync
19801         oal_expect_read_count "${stats}" 1
19802
19803         do_facet ost1 killall -TERM ofd_access_log_reader
19804         wait
19805         rc=$?
19806         if ((rc != 0)); then
19807                 error "ofd_access_log_reader exited with rc = '${rc}'"
19808         fi
19809 }
19810 run_test 165e "ofd_access_log MDT index filter works"
19811
19812 test_165f() {
19813         local trace="/tmp/${tfile}.trace"
19814         local rc
19815         local count
19816
19817         setup_165
19818         do_facet ost1 timeout 60 ofd_access_log_reader \
19819                 --exit-on-close --debug=- --trace=- > "${trace}" &
19820         sleep 5
19821         stop ost1
19822
19823         wait
19824         rc=$?
19825
19826         if ((rc != 0)); then
19827                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19828                 cat "${trace}"
19829                 exit 1
19830         fi
19831 }
19832 run_test 165f "ofd_access_log_reader --exit-on-close works"
19833
19834 test_169() {
19835         # do directio so as not to populate the page cache
19836         log "creating a 10 Mb file"
19837         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19838                 error "multiop failed while creating a file"
19839         log "starting reads"
19840         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19841         log "truncating the file"
19842         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19843                 error "multiop failed while truncating the file"
19844         log "killing dd"
19845         kill %+ || true # reads might have finished
19846         echo "wait until dd is finished"
19847         wait
19848         log "removing the temporary file"
19849         rm -rf $DIR/$tfile || error "tmp file removal failed"
19850 }
19851 run_test 169 "parallel read and truncate should not deadlock"
19852
19853 test_170() {
19854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19855
19856         $LCTL clear     # bug 18514
19857         $LCTL debug_daemon start $TMP/${tfile}_log_good
19858         touch $DIR/$tfile
19859         $LCTL debug_daemon stop
19860         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19861                 error "sed failed to read log_good"
19862
19863         $LCTL debug_daemon start $TMP/${tfile}_log_good
19864         rm -rf $DIR/$tfile
19865         $LCTL debug_daemon stop
19866
19867         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19868                error "lctl df log_bad failed"
19869
19870         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19871         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19872
19873         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19874         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19875
19876         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19877                 error "bad_line good_line1 good_line2 are empty"
19878
19879         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19880         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19881         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19882
19883         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19884         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19885         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19886
19887         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19888                 error "bad_line_new good_line_new are empty"
19889
19890         local expected_good=$((good_line1 + good_line2*2))
19891
19892         rm -f $TMP/${tfile}*
19893         # LU-231, short malformed line may not be counted into bad lines
19894         if [ $bad_line -ne $bad_line_new ] &&
19895                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19896                 error "expected $bad_line bad lines, but got $bad_line_new"
19897                 return 1
19898         fi
19899
19900         if [ $expected_good -ne $good_line_new ]; then
19901                 error "expected $expected_good good lines, but got $good_line_new"
19902                 return 2
19903         fi
19904         true
19905 }
19906 run_test 170 "test lctl df to handle corrupted log ====================="
19907
19908 test_171() { # bug20592
19909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19910
19911         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19912         $LCTL set_param fail_loc=0x50e
19913         $LCTL set_param fail_val=3000
19914         multiop_bg_pause $DIR/$tfile O_s || true
19915         local MULTIPID=$!
19916         kill -USR1 $MULTIPID
19917         # cause log dump
19918         sleep 3
19919         wait $MULTIPID
19920         if dmesg | grep "recursive fault"; then
19921                 error "caught a recursive fault"
19922         fi
19923         $LCTL set_param fail_loc=0
19924         true
19925 }
19926 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19927
19928 test_172() {
19929
19930         #define OBD_FAIL_OBD_CLEANUP  0x60e
19931         $LCTL set_param fail_loc=0x60e
19932         umount $MOUNT || error "umount $MOUNT failed"
19933         stack_trap "mount_client $MOUNT"
19934
19935         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19936                 error "no client OBDs are remained"
19937
19938         $LCTL dl | while read devno state type name foo; do
19939                 case $type in
19940                 lov|osc|lmv|mdc)
19941                         $LCTL --device $name cleanup
19942                         $LCTL --device $name detach
19943                         ;;
19944                 *)
19945                         # skip server devices
19946                         ;;
19947                 esac
19948         done
19949
19950         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19951                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19952                 error "some client OBDs are still remained"
19953         fi
19954
19955 }
19956 run_test 172 "manual device removal with lctl cleanup/detach ======"
19957
19958 # it would be good to share it with obdfilter-survey/iokit-libecho code
19959 setup_obdecho_osc () {
19960         local rc=0
19961         local ost_nid=$1
19962         local obdfilter_name=$2
19963         echo "Creating new osc for $obdfilter_name on $ost_nid"
19964         # make sure we can find loopback nid
19965         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19966
19967         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19968                            ${obdfilter_name}_osc_UUID || rc=2; }
19969         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19970                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19971         return $rc
19972 }
19973
19974 cleanup_obdecho_osc () {
19975         local obdfilter_name=$1
19976         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19977         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19978         return 0
19979 }
19980
19981 obdecho_test() {
19982         local OBD=$1
19983         local node=$2
19984         local pages=${3:-64}
19985         local rc=0
19986         local id
19987
19988         local count=10
19989         local obd_size=$(get_obd_size $node $OBD)
19990         local page_size=$(get_page_size $node)
19991         if [[ -n "$obd_size" ]]; then
19992                 local new_count=$((obd_size / (pages * page_size / 1024)))
19993                 [[ $new_count -ge $count ]] || count=$new_count
19994         fi
19995
19996         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19997         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19998                            rc=2; }
19999         if [ $rc -eq 0 ]; then
20000             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
20001             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
20002         fi
20003         echo "New object id is $id"
20004         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
20005                            rc=4; }
20006         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
20007                            "test_brw $count w v $pages $id" || rc=4; }
20008         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
20009                            rc=4; }
20010         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
20011                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
20012         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
20013                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
20014         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
20015         return $rc
20016 }
20017
20018 test_180a() {
20019         skip "obdecho on osc is no longer supported"
20020 }
20021 run_test 180a "test obdecho on osc"
20022
20023 test_180b() {
20024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20025         remote_ost_nodsh && skip "remote OST with nodsh"
20026
20027         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
20028                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
20029                 error "failed to load module obdecho"
20030
20031         local target=$(do_facet ost1 $LCTL dl |
20032                        awk '/obdfilter/ { print $4; exit; }')
20033
20034         if [ -n "$target" ]; then
20035                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
20036         else
20037                 do_facet ost1 $LCTL dl
20038                 error "there is no obdfilter target on ost1"
20039         fi
20040 }
20041 run_test 180b "test obdecho directly on obdfilter"
20042
20043 test_180c() { # LU-2598
20044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20045         remote_ost_nodsh && skip "remote OST with nodsh"
20046         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
20047                 skip "Need MDS version at least 2.4.0"
20048
20049         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
20050                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
20051                 error "failed to load module obdecho"
20052
20053         local target=$(do_facet ost1 $LCTL dl |
20054                        awk '/obdfilter/ { print $4; exit; }')
20055
20056         if [ -n "$target" ]; then
20057                 local pages=16384 # 64MB bulk I/O RPC size
20058
20059                 obdecho_test "$target" ost1 "$pages" ||
20060                         error "obdecho_test with pages=$pages failed with $?"
20061         else
20062                 do_facet ost1 $LCTL dl
20063                 error "there is no obdfilter target on ost1"
20064         fi
20065 }
20066 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
20067
20068 test_181() { # bug 22177
20069         test_mkdir $DIR/$tdir
20070         # create enough files to index the directory
20071         createmany -o $DIR/$tdir/foobar 4000
20072         # print attributes for debug purpose
20073         lsattr -d .
20074         # open dir
20075         multiop_bg_pause $DIR/$tdir D_Sc || return 1
20076         MULTIPID=$!
20077         # remove the files & current working dir
20078         unlinkmany $DIR/$tdir/foobar 4000
20079         rmdir $DIR/$tdir
20080         kill -USR1 $MULTIPID
20081         wait $MULTIPID
20082         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
20083         return 0
20084 }
20085 run_test 181 "Test open-unlinked dir ========================"
20086
20087 test_182a() {
20088         local fcount=1000
20089         local tcount=10
20090
20091         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20092
20093         $LCTL set_param mdc.*.rpc_stats=clear
20094
20095         for (( i = 0; i < $tcount; i++ )) ; do
20096                 mkdir $DIR/$tdir/$i
20097         done
20098
20099         for (( i = 0; i < $tcount; i++ )) ; do
20100                 createmany -o $DIR/$tdir/$i/f- $fcount &
20101         done
20102         wait
20103
20104         for (( i = 0; i < $tcount; i++ )) ; do
20105                 unlinkmany $DIR/$tdir/$i/f- $fcount &
20106         done
20107         wait
20108
20109         $LCTL get_param mdc.*.rpc_stats
20110
20111         rm -rf $DIR/$tdir
20112 }
20113 run_test 182a "Test parallel modify metadata operations from mdc"
20114
20115 test_182b() {
20116         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20117         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20118         local dcount=1000
20119         local tcount=10
20120         local stime
20121         local etime
20122         local delta
20123
20124         do_facet mds1 $LCTL list_param \
20125                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
20126                 skip "MDS lacks parallel RPC handling"
20127
20128         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20129
20130         rpc_count=$(do_facet mds1 $LCTL get_param -n \
20131                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
20132
20133         stime=$(date +%s)
20134         createmany -i 0 -d $DIR/$tdir/t- $tcount
20135
20136         for (( i = 0; i < $tcount; i++ )) ; do
20137                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20138         done
20139         wait
20140         etime=$(date +%s)
20141         delta=$((etime - stime))
20142         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
20143
20144         stime=$(date +%s)
20145         for (( i = 0; i < $tcount; i++ )) ; do
20146                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
20147         done
20148         wait
20149         etime=$(date +%s)
20150         delta=$((etime - stime))
20151         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
20152
20153         rm -rf $DIR/$tdir
20154
20155         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20156
20157         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
20158
20159         stime=$(date +%s)
20160         createmany -i 0 -d $DIR/$tdir/t- $tcount
20161
20162         for (( i = 0; i < $tcount; i++ )) ; do
20163                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
20164         done
20165         wait
20166         etime=$(date +%s)
20167         delta=$((etime - stime))
20168         echo "Time for file creation $delta sec for 1 RPC sent at a time"
20169
20170         stime=$(date +%s)
20171         for (( i = 0; i < $tcount; i++ )) ; do
20172                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
20173         done
20174         wait
20175         etime=$(date +%s)
20176         delta=$((etime - stime))
20177         echo "Time for file removal $delta sec for 1 RPC sent at a time"
20178
20179         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
20180 }
20181 run_test 182b "Test parallel modify metadata operations from osp"
20182
20183 test_183() { # LU-2275
20184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20185         remote_mds_nodsh && skip "remote MDS with nodsh"
20186         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
20187                 skip "Need MDS version at least 2.3.56"
20188
20189         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20190         echo aaa > $DIR/$tdir/$tfile
20191
20192 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
20193         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
20194
20195         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
20196         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
20197
20198         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20199
20200         # Flush negative dentry cache
20201         touch $DIR/$tdir/$tfile
20202
20203         # We are not checking for any leaked references here, they'll
20204         # become evident next time we do cleanup with module unload.
20205         rm -rf $DIR/$tdir
20206 }
20207 run_test 183 "No crash or request leak in case of strange dispositions ========"
20208
20209 # test suite 184 is for LU-2016, LU-2017
20210 test_184a() {
20211         check_swap_layouts_support
20212
20213         dir0=$DIR/$tdir/$testnum
20214         test_mkdir -p -c1 $dir0
20215         ref1=/etc/passwd
20216         ref2=/etc/group
20217         file1=$dir0/f1
20218         file2=$dir0/f2
20219         $LFS setstripe -c1 $file1
20220         cp $ref1 $file1
20221         $LFS setstripe -c2 $file2
20222         cp $ref2 $file2
20223         gen1=$($LFS getstripe -g $file1)
20224         gen2=$($LFS getstripe -g $file2)
20225
20226         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20227         gen=$($LFS getstripe -g $file1)
20228         [[ $gen1 != $gen ]] ||
20229                 error "Layout generation on $file1 does not change"
20230         gen=$($LFS getstripe -g $file2)
20231         [[ $gen2 != $gen ]] ||
20232                 error "Layout generation on $file2 does not change"
20233
20234         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20235         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20236
20237         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20238 }
20239 run_test 184a "Basic layout swap"
20240
20241 test_184b() {
20242         check_swap_layouts_support
20243
20244         dir0=$DIR/$tdir/$testnum
20245         mkdir -p $dir0 || error "creating dir $dir0"
20246         file1=$dir0/f1
20247         file2=$dir0/f2
20248         file3=$dir0/f3
20249         dir1=$dir0/d1
20250         dir2=$dir0/d2
20251         mkdir $dir1 $dir2
20252         $LFS setstripe -c1 $file1
20253         $LFS setstripe -c2 $file2
20254         $LFS setstripe -c1 $file3
20255         chown $RUNAS_ID $file3
20256         gen1=$($LFS getstripe -g $file1)
20257         gen2=$($LFS getstripe -g $file2)
20258
20259         $LFS swap_layouts $dir1 $dir2 &&
20260                 error "swap of directories layouts should fail"
20261         $LFS swap_layouts $dir1 $file1 &&
20262                 error "swap of directory and file layouts should fail"
20263         $RUNAS $LFS swap_layouts $file1 $file2 &&
20264                 error "swap of file we cannot write should fail"
20265         $LFS swap_layouts $file1 $file3 &&
20266                 error "swap of file with different owner should fail"
20267         /bin/true # to clear error code
20268 }
20269 run_test 184b "Forbidden layout swap (will generate errors)"
20270
20271 test_184c() {
20272         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20273         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20274         check_swap_layouts_support
20275         check_swap_layout_no_dom $DIR
20276
20277         local dir0=$DIR/$tdir/$testnum
20278         mkdir -p $dir0 || error "creating dir $dir0"
20279
20280         local ref1=$dir0/ref1
20281         local ref2=$dir0/ref2
20282         local file1=$dir0/file1
20283         local file2=$dir0/file2
20284         # create a file large enough for the concurrent test
20285         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20286         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20287         echo "ref file size: ref1($(stat -c %s $ref1))," \
20288              "ref2($(stat -c %s $ref2))"
20289
20290         cp $ref2 $file2
20291         dd if=$ref1 of=$file1 bs=16k &
20292         local DD_PID=$!
20293
20294         # Make sure dd starts to copy file, but wait at most 5 seconds
20295         local loops=0
20296         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20297
20298         $LFS swap_layouts $file1 $file2
20299         local rc=$?
20300         wait $DD_PID
20301         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20302         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20303
20304         # how many bytes copied before swapping layout
20305         local copied=$(stat -c %s $file2)
20306         local remaining=$(stat -c %s $ref1)
20307         remaining=$((remaining - copied))
20308         echo "Copied $copied bytes before swapping layout..."
20309
20310         cmp -n $copied $file1 $ref2 | grep differ &&
20311                 error "Content mismatch [0, $copied) of ref2 and file1"
20312         cmp -n $copied $file2 $ref1 ||
20313                 error "Content mismatch [0, $copied) of ref1 and file2"
20314         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20315                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20316
20317         # clean up
20318         rm -f $ref1 $ref2 $file1 $file2
20319 }
20320 run_test 184c "Concurrent write and layout swap"
20321
20322 test_184d() {
20323         check_swap_layouts_support
20324         check_swap_layout_no_dom $DIR
20325         [ -z "$(which getfattr 2>/dev/null)" ] &&
20326                 skip_env "no getfattr command"
20327
20328         local file1=$DIR/$tdir/$tfile-1
20329         local file2=$DIR/$tdir/$tfile-2
20330         local file3=$DIR/$tdir/$tfile-3
20331         local lovea1
20332         local lovea2
20333
20334         mkdir -p $DIR/$tdir
20335         touch $file1 || error "create $file1 failed"
20336         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20337                 error "create $file2 failed"
20338         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20339                 error "create $file3 failed"
20340         lovea1=$(get_layout_param $file1)
20341
20342         $LFS swap_layouts $file2 $file3 ||
20343                 error "swap $file2 $file3 layouts failed"
20344         $LFS swap_layouts $file1 $file2 ||
20345                 error "swap $file1 $file2 layouts failed"
20346
20347         lovea2=$(get_layout_param $file2)
20348         echo "$lovea1"
20349         echo "$lovea2"
20350         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20351
20352         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20353         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20354 }
20355 run_test 184d "allow stripeless layouts swap"
20356
20357 test_184e() {
20358         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20359                 skip "Need MDS version at least 2.6.94"
20360         check_swap_layouts_support
20361         check_swap_layout_no_dom $DIR
20362         [ -z "$(which getfattr 2>/dev/null)" ] &&
20363                 skip_env "no getfattr command"
20364
20365         local file1=$DIR/$tdir/$tfile-1
20366         local file2=$DIR/$tdir/$tfile-2
20367         local file3=$DIR/$tdir/$tfile-3
20368         local lovea
20369
20370         mkdir -p $DIR/$tdir
20371         touch $file1 || error "create $file1 failed"
20372         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20373                 error "create $file2 failed"
20374         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20375                 error "create $file3 failed"
20376
20377         $LFS swap_layouts $file1 $file2 ||
20378                 error "swap $file1 $file2 layouts failed"
20379
20380         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20381         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20382
20383         echo 123 > $file1 || error "Should be able to write into $file1"
20384
20385         $LFS swap_layouts $file1 $file3 ||
20386                 error "swap $file1 $file3 layouts failed"
20387
20388         echo 123 > $file1 || error "Should be able to write into $file1"
20389
20390         rm -rf $file1 $file2 $file3
20391 }
20392 run_test 184e "Recreate layout after stripeless layout swaps"
20393
20394 test_184f() {
20395         # Create a file with name longer than sizeof(struct stat) ==
20396         # 144 to see if we can get chars from the file name to appear
20397         # in the returned striping. Note that 'f' == 0x66.
20398         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20399
20400         mkdir -p $DIR/$tdir
20401         mcreate $DIR/$tdir/$file
20402         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20403                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20404         fi
20405 }
20406 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20407
20408 test_185() { # LU-2441
20409         # LU-3553 - no volatile file support in old servers
20410         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20411                 skip "Need MDS version at least 2.3.60"
20412
20413         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20414         touch $DIR/$tdir/spoo
20415         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20416         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20417                 error "cannot create/write a volatile file"
20418         [ "$FILESET" == "" ] &&
20419         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20420                 error "FID is still valid after close"
20421
20422         multiop_bg_pause $DIR/$tdir Vw4096_c
20423         local multi_pid=$!
20424
20425         local OLD_IFS=$IFS
20426         IFS=":"
20427         local fidv=($fid)
20428         IFS=$OLD_IFS
20429         # assume that the next FID for this client is sequential, since stdout
20430         # is unfortunately eaten by multiop_bg_pause
20431         local n=$((${fidv[1]} + 1))
20432         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20433         if [ "$FILESET" == "" ]; then
20434                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20435                         error "FID is missing before close"
20436         fi
20437         kill -USR1 $multi_pid
20438         # 1 second delay, so if mtime change we will see it
20439         sleep 1
20440         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20441         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20442 }
20443 run_test 185 "Volatile file support"
20444
20445 function create_check_volatile() {
20446         local idx=$1
20447         local tgt
20448
20449         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20450         local PID=$!
20451         sleep 1
20452         local FID=$(cat /tmp/${tfile}.fid)
20453         [ "$FID" == "" ] && error "can't get FID for volatile"
20454         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20455         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20456         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20457         kill -USR1 $PID
20458         wait
20459         sleep 1
20460         cancel_lru_locks mdc # flush opencache
20461         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20462         return 0
20463 }
20464
20465 test_185a(){
20466         # LU-12516 - volatile creation via .lustre
20467         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20468                 skip "Need MDS version at least 2.3.55"
20469
20470         create_check_volatile 0
20471         [ $MDSCOUNT -lt 2 ] && return 0
20472
20473         # DNE case
20474         create_check_volatile 1
20475
20476         return 0
20477 }
20478 run_test 185a "Volatile file creation in .lustre/fid/"
20479
20480 test_187a() {
20481         remote_mds_nodsh && skip "remote MDS with nodsh"
20482         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20483                 skip "Need MDS version at least 2.3.0"
20484
20485         local dir0=$DIR/$tdir/$testnum
20486         mkdir -p $dir0 || error "creating dir $dir0"
20487
20488         local file=$dir0/file1
20489         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20490         stack_trap "rm -f $file"
20491         local dv1=$($LFS data_version $file)
20492         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20493         local dv2=$($LFS data_version $file)
20494         [[ $dv1 != $dv2 ]] ||
20495                 error "data version did not change on write $dv1 == $dv2"
20496 }
20497 run_test 187a "Test data version change"
20498
20499 test_187b() {
20500         remote_mds_nodsh && skip "remote MDS with nodsh"
20501         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20502                 skip "Need MDS version at least 2.3.0"
20503
20504         local dir0=$DIR/$tdir/$testnum
20505         mkdir -p $dir0 || error "creating dir $dir0"
20506
20507         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20508         [[ ${DV[0]} != ${DV[1]} ]] ||
20509                 error "data version did not change on write"\
20510                       " ${DV[0]} == ${DV[1]}"
20511
20512         # clean up
20513         rm -f $file1
20514 }
20515 run_test 187b "Test data version change on volatile file"
20516
20517 test_200() {
20518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20519         remote_mgs_nodsh && skip "remote MGS with nodsh"
20520         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20521
20522         local POOL=${POOL:-cea1}
20523         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20524         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20525         # Pool OST targets
20526         local first_ost=0
20527         local last_ost=$(($OSTCOUNT - 1))
20528         local ost_step=2
20529         local ost_list=$(seq $first_ost $ost_step $last_ost)
20530         local ost_range="$first_ost $last_ost $ost_step"
20531         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20532         local file_dir=$POOL_ROOT/file_tst
20533         local subdir=$test_path/subdir
20534         local rc=0
20535
20536         while : ; do
20537                 # former test_200a test_200b
20538                 pool_add $POOL                          || { rc=$? ; break; }
20539                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20540                 # former test_200c test_200d
20541                 mkdir -p $test_path
20542                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20543                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20544                 mkdir -p $subdir
20545                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20546                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20547                                                         || { rc=$? ; break; }
20548                 # former test_200e test_200f
20549                 local files=$((OSTCOUNT*3))
20550                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20551                                                         || { rc=$? ; break; }
20552                 pool_create_files $POOL $file_dir $files "$ost_list" \
20553                                                         || { rc=$? ; break; }
20554                 # former test_200g test_200h
20555                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20556                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20557
20558                 # former test_201a test_201b test_201c
20559                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20560
20561                 local f=$test_path/$tfile
20562                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20563                 pool_remove $POOL $f                    || { rc=$? ; break; }
20564                 break
20565         done
20566
20567         destroy_test_pools
20568
20569         return $rc
20570 }
20571 run_test 200 "OST pools"
20572
20573 # usage: default_attr <count | size | offset>
20574 default_attr() {
20575         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20576 }
20577
20578 # usage: check_default_stripe_attr
20579 check_default_stripe_attr() {
20580         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20581         case $1 in
20582         --stripe-count|-c)
20583                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20584         --stripe-size|-S)
20585                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20586         --stripe-index|-i)
20587                 EXPECTED=-1;;
20588         *)
20589                 error "unknown getstripe attr '$1'"
20590         esac
20591
20592         [ $ACTUAL == $EXPECTED ] ||
20593                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20594 }
20595
20596 test_204a() {
20597         test_mkdir $DIR/$tdir
20598         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20599
20600         check_default_stripe_attr --stripe-count
20601         check_default_stripe_attr --stripe-size
20602         check_default_stripe_attr --stripe-index
20603 }
20604 run_test 204a "Print default stripe attributes"
20605
20606 test_204b() {
20607         test_mkdir $DIR/$tdir
20608         $LFS setstripe --stripe-count 1 $DIR/$tdir
20609
20610         check_default_stripe_attr --stripe-size
20611         check_default_stripe_attr --stripe-index
20612 }
20613 run_test 204b "Print default stripe size and offset"
20614
20615 test_204c() {
20616         test_mkdir $DIR/$tdir
20617         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20618
20619         check_default_stripe_attr --stripe-count
20620         check_default_stripe_attr --stripe-index
20621 }
20622 run_test 204c "Print default stripe count and offset"
20623
20624 test_204d() {
20625         test_mkdir $DIR/$tdir
20626         $LFS setstripe --stripe-index 0 $DIR/$tdir
20627
20628         check_default_stripe_attr --stripe-count
20629         check_default_stripe_attr --stripe-size
20630 }
20631 run_test 204d "Print default stripe count and size"
20632
20633 test_204e() {
20634         test_mkdir $DIR/$tdir
20635         $LFS setstripe -d $DIR/$tdir
20636
20637         # LU-16904 check if root is set as PFL layout
20638         local numcomp=$($LFS getstripe --component-count $MOUNT)
20639
20640         if [[ $numcomp -gt 0 ]]; then
20641                 check_default_stripe_attr --stripe-count
20642         else
20643                 check_default_stripe_attr --stripe-count --raw
20644         fi
20645         check_default_stripe_attr --stripe-size --raw
20646         check_default_stripe_attr --stripe-index --raw
20647 }
20648 run_test 204e "Print raw stripe attributes"
20649
20650 test_204f() {
20651         test_mkdir $DIR/$tdir
20652         $LFS setstripe --stripe-count 1 $DIR/$tdir
20653
20654         check_default_stripe_attr --stripe-size --raw
20655         check_default_stripe_attr --stripe-index --raw
20656 }
20657 run_test 204f "Print raw stripe size and offset"
20658
20659 test_204g() {
20660         test_mkdir $DIR/$tdir
20661         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20662
20663         check_default_stripe_attr --stripe-count --raw
20664         check_default_stripe_attr --stripe-index --raw
20665 }
20666 run_test 204g "Print raw stripe count and offset"
20667
20668 test_204h() {
20669         test_mkdir $DIR/$tdir
20670         $LFS setstripe --stripe-index 0 $DIR/$tdir
20671
20672         check_default_stripe_attr --stripe-count --raw
20673         check_default_stripe_attr --stripe-size --raw
20674 }
20675 run_test 204h "Print raw stripe count and size"
20676
20677 # Figure out which job scheduler is being used, if any,
20678 # or use a fake one
20679 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20680         JOBENV=SLURM_JOB_ID
20681 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20682         JOBENV=LSB_JOBID
20683 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20684         JOBENV=PBS_JOBID
20685 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20686         JOBENV=LOADL_STEP_ID
20687 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20688         JOBENV=JOB_ID
20689 else
20690         $LCTL list_param jobid_name > /dev/null 2>&1
20691         if [ $? -eq 0 ]; then
20692                 JOBENV=nodelocal
20693         else
20694                 JOBENV=FAKE_JOBID
20695         fi
20696 fi
20697 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20698
20699 verify_jobstats() {
20700         local cmd=($1)
20701         shift
20702         local facets="$@"
20703
20704 # we don't really need to clear the stats for this test to work, since each
20705 # command has a unique jobid, but it makes debugging easier if needed.
20706 #       for facet in $facets; do
20707 #               local dev=$(convert_facet2label $facet)
20708 #               # clear old jobstats
20709 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20710 #       done
20711
20712         # use a new JobID for each test, or we might see an old one
20713         [ "$JOBENV" = "FAKE_JOBID" ] &&
20714                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20715
20716         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20717
20718         [ "$JOBENV" = "nodelocal" ] && {
20719                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20720                 $LCTL set_param jobid_name=$FAKE_JOBID
20721                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20722         }
20723
20724         log "Test: ${cmd[*]}"
20725         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20726
20727         if [ $JOBENV = "FAKE_JOBID" ]; then
20728                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20729         else
20730                 ${cmd[*]}
20731         fi
20732
20733         # all files are created on OST0000
20734         for facet in $facets; do
20735                 local stats="*.$(convert_facet2label $facet).job_stats"
20736
20737                 # strip out libtool wrappers for in-tree executables
20738                 if (( $(do_facet $facet lctl get_param $stats |
20739                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20740                         do_facet $facet lctl get_param $stats
20741                         error "No jobstats for $JOBVAL found on $facet::$stats"
20742                 fi
20743         done
20744 }
20745
20746 jobstats_set() {
20747         local new_jobenv=$1
20748
20749         set_persistent_param_and_check client "jobid_var" \
20750                 "$FSNAME.sys.jobid_var" $new_jobenv
20751 }
20752
20753 test_205a() { # Job stats
20754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20755         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20756                 skip "Need MDS version with at least 2.7.1"
20757         remote_mgs_nodsh && skip "remote MGS with nodsh"
20758         remote_mds_nodsh && skip "remote MDS with nodsh"
20759         remote_ost_nodsh && skip "remote OST with nodsh"
20760         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20761                 skip "Server doesn't support jobstats"
20762         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20763
20764         local old_jobenv=$($LCTL get_param -n jobid_var)
20765         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20766         stack_trap "jobstats_set $old_jobenv" EXIT
20767
20768         changelog_register
20769
20770         local old_jobid_name=$($LCTL get_param jobid_name)
20771         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20772
20773         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20774                                 mdt.*.job_cleanup_interval | head -n 1)
20775         local new_interval=5
20776         do_facet $SINGLEMDS \
20777                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20778         stack_trap "do_facet $SINGLEMDS \
20779                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20780         local start=$SECONDS
20781
20782         local cmd
20783         # mkdir
20784         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20785         verify_jobstats "$cmd" "$SINGLEMDS"
20786         # rmdir
20787         cmd="rmdir $DIR/$tdir"
20788         verify_jobstats "$cmd" "$SINGLEMDS"
20789         # mkdir on secondary MDT
20790         if [ $MDSCOUNT -gt 1 ]; then
20791                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20792                 verify_jobstats "$cmd" "mds2"
20793         fi
20794         # mknod
20795         cmd="mknod $DIR/$tfile c 1 3"
20796         verify_jobstats "$cmd" "$SINGLEMDS"
20797         # unlink
20798         cmd="rm -f $DIR/$tfile"
20799         verify_jobstats "$cmd" "$SINGLEMDS"
20800         # create all files on OST0000 so verify_jobstats can find OST stats
20801         # open & close
20802         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20803         verify_jobstats "$cmd" "$SINGLEMDS"
20804         # setattr
20805         cmd="touch $DIR/$tfile"
20806         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20807         # write
20808         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20809         verify_jobstats "$cmd" "ost1"
20810         # read
20811         cancel_lru_locks osc
20812         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20813         verify_jobstats "$cmd" "ost1"
20814         # truncate
20815         cmd="$TRUNCATE $DIR/$tfile 0"
20816         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20817         # rename
20818         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20819         verify_jobstats "$cmd" "$SINGLEMDS"
20820         # jobstats expiry - sleep until old stats should be expired
20821         local left=$((new_interval + 5 - (SECONDS - start)))
20822         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20823                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20824                         "0" $left
20825         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20826         verify_jobstats "$cmd" "$SINGLEMDS"
20827         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20828             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20829
20830         # Ensure that jobid are present in changelog (if supported by MDS)
20831         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20832                 changelog_dump | tail -10
20833                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20834                 [ $jobids -eq 9 ] ||
20835                         error "Wrong changelog jobid count $jobids != 9"
20836
20837                 # LU-5862
20838                 JOBENV="disable"
20839                 jobstats_set $JOBENV
20840                 touch $DIR/$tfile
20841                 changelog_dump | grep $tfile
20842                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20843                 [ $jobids -eq 0 ] ||
20844                         error "Unexpected jobids when jobid_var=$JOBENV"
20845         fi
20846
20847         # test '%j' access to environment variable - if supported
20848         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20849                 JOBENV="JOBCOMPLEX"
20850                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20851
20852                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20853         fi
20854
20855         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20856                 JOBENV="JOBCOMPLEX"
20857                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20858
20859                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20860         fi
20861
20862         # test '%j' access to per-session jobid - if supported
20863         if lctl list_param jobid_this_session > /dev/null 2>&1
20864         then
20865                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20866                 lctl set_param jobid_this_session=$USER
20867
20868                 JOBENV="JOBCOMPLEX"
20869                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20870
20871                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20872         fi
20873 }
20874 run_test 205a "Verify job stats"
20875
20876 # LU-13117, LU-13597, LU-16599
20877 test_205b() {
20878         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20879                 skip "Need MDS version at least 2.13.54.91"
20880
20881         local job_stats="mdt.*.job_stats"
20882         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20883
20884         do_facet mds1 $LCTL set_param $job_stats=clear
20885
20886         # Setting jobid_var to USER might not be supported
20887         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20888         $LCTL set_param jobid_var=USER || true
20889         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20890         $LCTL set_param jobid_name="%j.%e.%u"
20891
20892         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20893         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20894                 { do_facet mds1 $LCTL get_param $job_stats;
20895                   error "Unexpected jobid found"; }
20896         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20897                 { do_facet mds1 $LCTL get_param $job_stats;
20898                   error "wrong job_stats format found"; }
20899
20900         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20901                 echo "MDS does not yet escape jobid" && return 0
20902
20903         mkdir_on_mdt0 $DIR/$tdir
20904         $LCTL set_param jobid_var=TEST205b
20905         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20906         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20907                       awk '/has\\x20sp/ {print $3}')
20908         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20909                   error "jobid not escaped"; }
20910
20911         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20912                 # need to run such a command on mds1:
20913                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20914                 #
20915                 # there might be multiple MDTs on single mds server, so need to
20916                 # specifiy MDT0000. Or the command will fail due to other MDTs
20917                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20918                         error "cannot clear escaped jobid in job_stats";
20919         else
20920                 echo "MDS does not support clearing escaped jobid"
20921         fi
20922 }
20923 run_test 205b "Verify job stats jobid and output format"
20924
20925 # LU-13733
20926 test_205c() {
20927         $LCTL set_param llite.*.stats=0
20928         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20929         $LCTL get_param llite.*.stats
20930         $LCTL get_param llite.*.stats | grep \
20931                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20932                         error "wrong client stats format found"
20933 }
20934 run_test 205c "Verify client stats format"
20935
20936 test_205d() {
20937         local file=$DIR/$tdir/$tfile
20938
20939         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20940                 skip "need lustre >= 2.15.53 for lljobstat"
20941         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20942                 skip "need lustre >= 2.15.53 for lljobstat"
20943         verify_yaml_available || skip_env "YAML verification not installed"
20944
20945         test_mkdir -i 0 $DIR/$tdir
20946         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20947         stack_trap "rm -rf $DIR/$tdir"
20948
20949         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20950                 error "failed to write data to $file"
20951         mv $file $file.2
20952
20953         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20954         echo -n 'verify rename_stats...'
20955         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20956                 verify_yaml || error "rename_stats is not valid YAML"
20957         echo " OK"
20958
20959         echo -n 'verify mdt job_stats...'
20960         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20961                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20962         echo " OK"
20963
20964         echo -n 'verify ost job_stats...'
20965         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20966                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20967         echo " OK"
20968 }
20969 run_test 205d "verify the format of some stats files"
20970
20971 test_205e() {
20972         local ops_comma
20973         local file=$DIR/$tdir/$tfile
20974         local -a cli_params
20975
20976         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20977                 skip "need lustre >= 2.15.53 for lljobstat"
20978         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20979                 skip "need lustre >= 2.15.53 for lljobstat"
20980         verify_yaml_available || skip_env "YAML verification not installed"
20981
20982         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20983         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20984         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20985
20986         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20987         stack_trap "rm -rf $DIR/$tdir"
20988
20989         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20990                 error "failed to create $file on ost1"
20991         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20992                 error "failed to write data to $file"
20993
20994         do_facet mds1 "$LCTL get_param *.*.job_stats"
20995         do_facet ost1 "$LCTL get_param *.*.job_stats"
20996
20997         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20998         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20999                 error "The output of lljobstat is not an valid YAML"
21000
21001         # verify that job dd.0 does exist and has some ops on ost1
21002         # typically this line is like:
21003         # - 205e.dd.0:            {ops: 20, ...}
21004         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
21005                     awk '$2=="205e.dd.0:" {print $4}')
21006
21007         (( ${ops_comma%,} >= 10 )) ||
21008                 error "cannot find job 205e.dd.0 with ops >= 10"
21009 }
21010 run_test 205e "verify the output of lljobstat"
21011
21012 test_205f() {
21013         verify_yaml_available || skip_env "YAML verification not installed"
21014
21015         # check both qos_ost_weights and qos_mdt_weights
21016         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
21017         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
21018                 error "qos_ost_weights is not valid YAML"
21019 }
21020 run_test 205f "verify qos_ost_weights YAML format "
21021
21022 __test_205_jobstats_dump() {
21023         local -a pids
21024         local nbr_instance=$1
21025
21026         while true; do
21027                 if (( ${#pids[@]} >= nbr_instance )); then
21028                         wait ${pids[@]}
21029                         pids=()
21030                 fi
21031
21032                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
21033                 pids+=( $! )
21034         done
21035 }
21036
21037 __test_205_cleanup() {
21038         kill $@
21039         # Clear all job entries
21040         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
21041 }
21042
21043 test_205g() {
21044         local -a mds1_params
21045         local -a cli_params
21046         local pids
21047         local interval=5
21048
21049         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
21050         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
21051         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
21052
21053         cli_params=( $($LCTL get_param jobid_name jobid_var) )
21054         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
21055         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
21056
21057         # start jobs loop
21058         export TEST205G_ID=205g
21059         stack_trap "unset TEST205G_ID" EXIT
21060         while true; do
21061                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
21062         done & pids="$! "
21063
21064         __test_205_jobstats_dump 4 & pids+="$! "
21065         stack_trap "__test_205_cleanup $pids" EXIT INT
21066
21067         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
21068 }
21069 run_test 205g "stress test for job_stats procfile"
21070
21071 test_205h() {
21072         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
21073                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
21074         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
21075
21076         local dir=$DIR/$tdir
21077         local f=$dir/$tfile
21078         local f2=$dir/$tfile-2
21079         local f3=$dir/$tfile-3
21080         local subdir=$DIR/dir
21081         local val
21082
21083         local mdts=$(comma_list $(mdts_nodes))
21084         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
21085         local client_saved=$($LCTL get_param -n jobid_var)
21086
21087         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
21088         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
21089
21090         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
21091                 error "failed to set job_xattr parameter to user.job"
21092         $LCTL set_param jobid_var=procname.uid ||
21093                 error "failed to set jobid_var parameter"
21094
21095         test_mkdir $dir
21096
21097         touch $f
21098         val=$(getfattr -n user.job $f | grep user.job)
21099         [[ $val = user.job=\"touch.0\" ]] ||
21100                 error "expected user.job=\"touch.0\", got '$val'"
21101
21102         mkdir $subdir
21103         val=$(getfattr -n user.job $subdir | grep user.job)
21104         [[ $val = user.job=\"mkdir.0\" ]] ||
21105                 error "expected user.job=\"mkdir.0\", got '$val'"
21106
21107         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
21108                 error "failed to set job_xattr parameter to NONE"
21109
21110         touch $f2
21111         val=$(getfattr -d $f2)
21112         [[ -z $val ]] ||
21113                 error "expected no user xattr, got '$val'"
21114
21115         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
21116                 error "failed to set job_xattr parameter to trusted.job"
21117
21118         touch $f3
21119         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
21120         [[ $val = trusted.job=\"touch.0\" ]] ||
21121                 error "expected trusted.job=\"touch.0\", got '$val'"
21122 }
21123 run_test 205h "check jobid xattr is stored correctly"
21124
21125 test_205i() {
21126         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
21127                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
21128
21129         local mdts=$(comma_list $(mdts_nodes))
21130         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
21131
21132         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
21133
21134         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
21135                 error "failed to set mdt.*.job_xattr to user.1234567"
21136
21137         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
21138                 error "failed to reject too long job_xattr name"
21139
21140         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
21141                 error "failed to reject job_xattr name in bad format"
21142
21143         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
21144                 error "failed to reject job_xattr name with invalid character"
21145
21146         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
21147                         xargs $LCTL set_param" &&
21148                 error "failed to reject job_xattr name with non-ascii character"
21149
21150         return 0
21151 }
21152 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
21153
21154 # LU-1480, LU-1773 and LU-1657
21155 test_206() {
21156         mkdir -p $DIR/$tdir
21157         $LFS setstripe -c -1 $DIR/$tdir
21158 #define OBD_FAIL_LOV_INIT 0x1403
21159         $LCTL set_param fail_loc=0xa0001403
21160         $LCTL set_param fail_val=1
21161         touch $DIR/$tdir/$tfile || true
21162 }
21163 run_test 206 "fail lov_init_raid0() doesn't lbug"
21164
21165 test_207a() {
21166         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21167         local fsz=`stat -c %s $DIR/$tfile`
21168         cancel_lru_locks mdc
21169
21170         # do not return layout in getattr intent
21171 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
21172         $LCTL set_param fail_loc=0x170
21173         local sz=`stat -c %s $DIR/$tfile`
21174
21175         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
21176
21177         rm -rf $DIR/$tfile
21178 }
21179 run_test 207a "can refresh layout at glimpse"
21180
21181 test_207b() {
21182         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21183         local cksum=`md5sum $DIR/$tfile`
21184         local fsz=`stat -c %s $DIR/$tfile`
21185         cancel_lru_locks mdc
21186         cancel_lru_locks osc
21187
21188         # do not return layout in getattr intent
21189 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
21190         $LCTL set_param fail_loc=0x171
21191
21192         # it will refresh layout after the file is opened but before read issues
21193         echo checksum is "$cksum"
21194         echo "$cksum" |md5sum -c --quiet || error "file differs"
21195
21196         rm -rf $DIR/$tfile
21197 }
21198 run_test 207b "can refresh layout at open"
21199
21200 test_208() {
21201         # FIXME: in this test suite, only RD lease is used. This is okay
21202         # for now as only exclusive open is supported. After generic lease
21203         # is done, this test suite should be revised. - Jinshan
21204
21205         remote_mds_nodsh && skip "remote MDS with nodsh"
21206         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21207                 skip "Need MDS version at least 2.4.52"
21208
21209         echo "==== test 1: verify get lease work"
21210         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21211
21212         echo "==== test 2: verify lease can be broken by upcoming open"
21213         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21214         local PID=$!
21215         sleep 2
21216
21217         $MULTIOP $DIR/$tfile oO_RDWR:c
21218         kill -USR1 $PID && wait $PID || error "break lease error"
21219
21220         echo "==== test 3: verify lease can't be granted if an open already exists"
21221         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21222         local PID=$!
21223         sleep 2
21224
21225         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21226         kill -USR1 $PID && wait $PID || error "open file error"
21227
21228         echo "==== test 4: lease can sustain over recovery"
21229         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21230         PID=$!
21231         sleep 2
21232
21233         fail mds1
21234
21235         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21236
21237         echo "==== test 5: lease broken can't be regained by replay"
21238         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21239         PID=$!
21240         sleep 2
21241
21242         # open file to break lease and then recovery
21243         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21244         fail mds1
21245
21246         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21247
21248         rm -f $DIR/$tfile
21249 }
21250 run_test 208 "Exclusive open"
21251
21252 test_209() {
21253         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21254                 skip_env "must have disp_stripe"
21255
21256         touch $DIR/$tfile
21257         sync; sleep 5; sync;
21258
21259         echo 3 > /proc/sys/vm/drop_caches
21260         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21261                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21262         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21263
21264         # open/close 500 times
21265         for i in $(seq 500); do
21266                 cat $DIR/$tfile
21267         done
21268
21269         echo 3 > /proc/sys/vm/drop_caches
21270         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21271                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21272         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21273
21274         echo "before: $req_before, after: $req_after"
21275         [ $((req_after - req_before)) -ge 300 ] &&
21276                 error "open/close requests are not freed"
21277         return 0
21278 }
21279 run_test 209 "read-only open/close requests should be freed promptly"
21280
21281 test_210() {
21282         local pid
21283
21284         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21285         pid=$!
21286         sleep 1
21287
21288         $LFS getstripe $DIR/$tfile
21289         kill -USR1 $pid
21290         wait $pid || error "multiop failed"
21291
21292         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21293         pid=$!
21294         sleep 1
21295
21296         $LFS getstripe $DIR/$tfile
21297         kill -USR1 $pid
21298         wait $pid || error "multiop failed"
21299 }
21300 run_test 210 "lfs getstripe does not break leases"
21301
21302 function test_211() {
21303         local PID
21304         local id
21305         local rc
21306
21307         stack_trap "rm -f $DIR/$tfile" EXIT
21308         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21309                 error "can't create file"
21310         $LFS mirror extend -N $DIR/$tfile ||
21311                 error "can't create a replica"
21312         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21313         $LFS getstripe $DIR/$tfile
21314         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21315         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21316
21317         $MULTIOP $DIR/$tfile OeW_E+eUc &
21318         PID=$!
21319         sleep 0.3
21320
21321         id=$($LFS getstripe $DIR/$tfile |
21322                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21323         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21324                 error "removed last in-sync replica?"
21325
21326         kill -USR1 $PID
21327         wait $PID
21328         (( $? == 0 )) || error "failed split broke the lease"
21329 }
21330 run_test 211 "failed mirror split doesn't break write lease"
21331
21332 test_212() {
21333         size=`date +%s`
21334         size=$((size % 8192 + 1))
21335         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21336         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21337         rm -f $DIR/f212 $DIR/f212.xyz
21338 }
21339 run_test 212 "Sendfile test ============================================"
21340
21341 test_213() {
21342         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21343         cancel_lru_locks osc
21344         lctl set_param fail_loc=0x8000040f
21345         # generate a read lock
21346         cat $DIR/$tfile > /dev/null
21347         # write to the file, it will try to cancel the above read lock.
21348         cat /etc/hosts >> $DIR/$tfile
21349 }
21350 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21351
21352 test_214() { # for bug 20133
21353         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21354         for (( i=0; i < 340; i++ )) ; do
21355                 touch $DIR/$tdir/d214c/a$i
21356         done
21357
21358         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21359         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21360         ls $DIR/d214c || error "ls $DIR/d214c failed"
21361         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21362         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21363 }
21364 run_test 214 "hash-indexed directory test - bug 20133"
21365
21366 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21367 create_lnet_proc_files() {
21368         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21369 }
21370
21371 # counterpart of create_lnet_proc_files
21372 remove_lnet_proc_files() {
21373         rm -f $TMP/lnet_$1.sys
21374 }
21375
21376 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21377 # 3rd arg as regexp for body
21378 check_lnet_proc_stats() {
21379         local l=$(cat "$TMP/lnet_$1" |wc -l)
21380         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21381
21382         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21383 }
21384
21385 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21386 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21387 # optional and can be regexp for 2nd line (lnet.routes case)
21388 check_lnet_proc_entry() {
21389         local blp=2          # blp stands for 'position of 1st line of body'
21390         [ -z "$5" ] || blp=3 # lnet.routes case
21391
21392         local l=$(cat "$TMP/lnet_$1" |wc -l)
21393         # subtracting one from $blp because the body can be empty
21394         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21395
21396         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21397                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21398
21399         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21400                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21401
21402         # bail out if any unexpected line happened
21403         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21404         [ "$?" != 0 ] || error "$2 misformatted"
21405 }
21406
21407 test_215() { # for bugs 18102, 21079, 21517
21408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21409
21410         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21411         local P='[1-9][0-9]*'           # positive numeric
21412         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21413         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21414         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21415         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21416         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21417         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21418
21419         local L1 # regexp for 1st line
21420         local L2 # regexp for 2nd line (optional)
21421         local BR # regexp for the rest (body)
21422
21423         # lnet.stats should look as 11 space-separated non-negative numerics
21424         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21425         create_lnet_proc_files "stats"
21426         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21427         remove_lnet_proc_files "stats"
21428
21429         # lnet.routes should look like this:
21430         # Routing disabled/enabled
21431         # net hops priority state router
21432         # where net is a string like tcp0, hops > 0, priority >= 0,
21433         # state is up/down,
21434         # router is a string like 192.168.1.1@tcp2
21435         L1="^Routing (disabled|enabled)$"
21436         L2="^net +hops +priority +state +router$"
21437         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21438         create_lnet_proc_files "routes"
21439         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21440         remove_lnet_proc_files "routes"
21441
21442         # lnet.routers should look like this:
21443         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21444         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21445         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21446         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21447         L1="^ref +rtr_ref +alive +router$"
21448         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21449         create_lnet_proc_files "routers"
21450         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21451         remove_lnet_proc_files "routers"
21452
21453         # lnet.peers should look like this:
21454         # nid refs state last max rtr min tx min queue
21455         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21456         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21457         # numeric (0 or >0 or <0), queue >= 0.
21458         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21459         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21460         create_lnet_proc_files "peers"
21461         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21462         remove_lnet_proc_files "peers"
21463
21464         # lnet.buffers  should look like this:
21465         # pages count credits min
21466         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21467         L1="^pages +count +credits +min$"
21468         BR="^ +$N +$N +$I +$I$"
21469         create_lnet_proc_files "buffers"
21470         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21471         remove_lnet_proc_files "buffers"
21472
21473         # lnet.nis should look like this:
21474         # nid status alive refs peer rtr max tx min
21475         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21476         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21477         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21478         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21479         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21480         create_lnet_proc_files "nis"
21481         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21482         remove_lnet_proc_files "nis"
21483
21484         # can we successfully write to lnet.stats?
21485         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21486 }
21487 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21488
21489 test_216() { # bug 20317
21490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21491         remote_ost_nodsh && skip "remote OST with nodsh"
21492
21493         local node
21494         local facets=$(get_facets OST)
21495         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21496
21497         save_lustre_params client "osc.*.contention_seconds" > $p
21498         save_lustre_params $facets \
21499                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21500         save_lustre_params $facets \
21501                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21502         save_lustre_params $facets \
21503                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21504         clear_stats osc.*.osc_stats
21505
21506         # agressive lockless i/o settings
21507         do_nodes $(comma_list $(osts_nodes)) \
21508                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21509                         ldlm.namespaces.filter-*.contended_locks=0 \
21510                         ldlm.namespaces.filter-*.contention_seconds=60"
21511         lctl set_param -n osc.*.contention_seconds=60
21512
21513         $DIRECTIO write $DIR/$tfile 0 10 4096
21514         $CHECKSTAT -s 40960 $DIR/$tfile
21515
21516         # disable lockless i/o
21517         do_nodes $(comma_list $(osts_nodes)) \
21518                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21519                         ldlm.namespaces.filter-*.contended_locks=32 \
21520                         ldlm.namespaces.filter-*.contention_seconds=0"
21521         lctl set_param -n osc.*.contention_seconds=0
21522         clear_stats osc.*.osc_stats
21523
21524         dd if=/dev/zero of=$DIR/$tfile count=0
21525         $CHECKSTAT -s 0 $DIR/$tfile
21526
21527         restore_lustre_params <$p
21528         rm -f $p
21529         rm $DIR/$tfile
21530 }
21531 run_test 216 "check lockless direct write updates file size and kms correctly"
21532
21533 test_217() { # bug 22430
21534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21535
21536         local node
21537
21538         for node in $(nodes_list); do
21539                 local nid=$(host_nids_address $node $NETTYPE)
21540                 local node_ip=$(do_node $node getent ahostsv4 $node |
21541                                 awk '{ print $1; exit; }')
21542
21543                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21544                 # if hostname matches any NID, use hostname for better testing
21545                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21546                         echo "lctl ping node $node@$NETTYPE"
21547                         lctl ping $node@$NETTYPE ||
21548                                 error "ping $node@$NETTYPE failed rc=$?"
21549                 else # otherwise, at least test 'lctl ping' is working
21550                         echo "lctl ping nid $(h2nettype $nid)"
21551                         lctl ping $(h2nettype $nid) ||
21552                                 error "ping $(h2nettype $nid) failed rc=$?"
21553                         echo "skipping $node (no hyphen detected)"
21554                 fi
21555         done
21556
21557         return 0
21558 }
21559 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21560
21561 test_218() {
21562         # do directio so as not to populate the page cache
21563         log "creating a 10 Mb file"
21564         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21565                 error "multiop failed while creating a file"
21566         log "starting reads"
21567         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21568         log "truncating the file"
21569         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21570                 error "multiop failed while truncating the file"
21571         log "killing dd"
21572         kill %+ || true # reads might have finished
21573         echo "wait until dd is finished"
21574         wait
21575         log "removing the temporary file"
21576         rm -rf $DIR/$tfile || error "tmp file removal failed"
21577 }
21578 run_test 218 "parallel read and truncate should not deadlock"
21579
21580 test_219() {
21581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21582
21583         # write one partial page
21584         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21585         # set no grant so vvp_io_commit_write will do sync write
21586         $LCTL set_param fail_loc=0x411
21587         # write a full page at the end of file
21588         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21589
21590         $LCTL set_param fail_loc=0
21591         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21592         $LCTL set_param fail_loc=0x411
21593         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21594
21595         # LU-4201
21596         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21597         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21598 }
21599 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21600
21601 test_220() { #LU-325
21602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21603         remote_ost_nodsh && skip "remote OST with nodsh"
21604         remote_mds_nodsh && skip "remote MDS with nodsh"
21605         remote_mgs_nodsh && skip "remote MGS with nodsh"
21606
21607         local OSTIDX=0
21608
21609         # create on MDT0000 so the last_id and next_id are correct
21610         mkdir_on_mdt0 $DIR/$tdir
21611         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21612         OST=${OST%_UUID}
21613
21614         # on the mdt's osc
21615         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21616         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21617                         osp.$mdtosc_proc1.prealloc_last_id)
21618         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21619                         osp.$mdtosc_proc1.prealloc_next_id)
21620
21621         $LFS df -i
21622
21623         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21624         #define OBD_FAIL_OST_ENOINO              0x229
21625         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21626         create_pool $FSNAME.$TESTNAME || return 1
21627         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21628
21629         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21630
21631         MDSOBJS=$((last_id - next_id))
21632         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21633
21634         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21635         echo "OST still has $count kbytes free"
21636
21637         echo "create $MDSOBJS files @next_id..."
21638         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21639
21640         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21641                         osp.$mdtosc_proc1.prealloc_last_id)
21642         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21643                         osp.$mdtosc_proc1.prealloc_next_id)
21644
21645         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21646         $LFS df -i
21647
21648         echo "cleanup..."
21649
21650         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21651         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21652
21653         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21654                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21655         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21656                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21657         echo "unlink $MDSOBJS files @$next_id..."
21658         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21659 }
21660 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21661
21662 test_221() {
21663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21664
21665         dd if=`which date` of=$MOUNT/date oflag=sync
21666         chmod +x $MOUNT/date
21667
21668         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21669         $LCTL set_param fail_loc=0x80001401
21670
21671         $MOUNT/date > /dev/null
21672         rm -f $MOUNT/date
21673 }
21674 run_test 221 "make sure fault and truncate race to not cause OOM"
21675
21676 test_222a () {
21677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21678
21679         rm -rf $DIR/$tdir
21680         test_mkdir $DIR/$tdir
21681         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21682         createmany -o $DIR/$tdir/$tfile 10
21683         cancel_lru_locks mdc
21684         cancel_lru_locks osc
21685         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21686         $LCTL set_param fail_loc=0x31a
21687         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21688         $LCTL set_param fail_loc=0
21689         rm -r $DIR/$tdir
21690 }
21691 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21692
21693 test_222b () {
21694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21695
21696         rm -rf $DIR/$tdir
21697         test_mkdir $DIR/$tdir
21698         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21699         createmany -o $DIR/$tdir/$tfile 10
21700         cancel_lru_locks mdc
21701         cancel_lru_locks osc
21702         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21703         $LCTL set_param fail_loc=0x31a
21704         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21705         $LCTL set_param fail_loc=0
21706 }
21707 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21708
21709 test_223 () {
21710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21711
21712         rm -rf $DIR/$tdir
21713         test_mkdir $DIR/$tdir
21714         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21715         createmany -o $DIR/$tdir/$tfile 10
21716         cancel_lru_locks mdc
21717         cancel_lru_locks osc
21718         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21719         $LCTL set_param fail_loc=0x31b
21720         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21721         $LCTL set_param fail_loc=0
21722         rm -r $DIR/$tdir
21723 }
21724 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21725
21726 test_224a() { # LU-1039, MRP-303
21727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21728         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21729         $LCTL set_param fail_loc=0x508
21730         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21731         $LCTL set_param fail_loc=0
21732         df $DIR
21733 }
21734 run_test 224a "Don't panic on bulk IO failure"
21735
21736 test_224bd_sub() { # LU-1039, MRP-303
21737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21738         local timeout=$1
21739
21740         shift
21741         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21742
21743         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21744
21745         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21746         cancel_lru_locks osc
21747         set_checksums 0
21748         stack_trap "set_checksums $ORIG_CSUM" EXIT
21749         local at_max_saved=0
21750
21751         # adaptive timeouts may prevent seeing the issue
21752         if at_is_enabled; then
21753                 at_max_saved=$(at_max_get mds)
21754                 at_max_set 0 mds client
21755                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21756         fi
21757
21758         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21759         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21760         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21761
21762         do_facet ost1 $LCTL set_param fail_loc=0
21763         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21764         df $DIR
21765 }
21766
21767 test_224b() {
21768         test_224bd_sub 3 error "dd failed"
21769 }
21770 run_test 224b "Don't panic on bulk IO failure"
21771
21772 test_224c() { # LU-6441
21773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21774         remote_mds_nodsh && skip "remote MDS with nodsh"
21775
21776         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21777         save_writethrough $p
21778         set_cache writethrough on
21779
21780         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21781         local at_max=$($LCTL get_param -n at_max)
21782         local timeout=$($LCTL get_param -n timeout)
21783         local test_at="at_max"
21784         local param_at="$FSNAME.sys.at_max"
21785         local test_timeout="timeout"
21786         local param_timeout="$FSNAME.sys.timeout"
21787
21788         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21789
21790         set_persistent_param_and_check client "$test_at" "$param_at" 0
21791         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21792
21793         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21794         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21795         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21796         stack_trap "rm -f $DIR/$tfile"
21797         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21798         sync
21799         do_facet ost1 "$LCTL set_param fail_loc=0"
21800
21801         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21802         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21803                 $timeout
21804
21805         $LCTL set_param -n $pages_per_rpc
21806         restore_lustre_params < $p
21807         rm -f $p
21808 }
21809 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21810
21811 test_224d() { # LU-11169
21812         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21813 }
21814 run_test 224d "Don't corrupt data on bulk IO timeout"
21815
21816 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21817 test_225a () {
21818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21819         if [ -z ${MDSSURVEY} ]; then
21820                 skip_env "mds-survey not found"
21821         fi
21822         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21823                 skip "Need MDS version at least 2.2.51"
21824
21825         local mds=$(facet_host $SINGLEMDS)
21826         local target=$(do_nodes $mds 'lctl dl' |
21827                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21828
21829         local cmd1="file_count=1000 thrhi=4"
21830         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21831         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21832         local cmd="$cmd1 $cmd2 $cmd3"
21833
21834         rm -f ${TMP}/mds_survey*
21835         echo + $cmd
21836         eval $cmd || error "mds-survey with zero-stripe failed"
21837         cat ${TMP}/mds_survey*
21838         rm -f ${TMP}/mds_survey*
21839 }
21840 run_test 225a "Metadata survey sanity with zero-stripe"
21841
21842 test_225b () {
21843         if [ -z ${MDSSURVEY} ]; then
21844                 skip_env "mds-survey not found"
21845         fi
21846         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21847                 skip "Need MDS version at least 2.2.51"
21848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21849         remote_mds_nodsh && skip "remote MDS with nodsh"
21850         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21851                 skip_env "Need to mount OST to test"
21852         fi
21853
21854         local mds=$(facet_host $SINGLEMDS)
21855         local target=$(do_nodes $mds 'lctl dl' |
21856                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21857
21858         local cmd1="file_count=1000 thrhi=4"
21859         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21860         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21861         local cmd="$cmd1 $cmd2 $cmd3"
21862
21863         rm -f ${TMP}/mds_survey*
21864         echo + $cmd
21865         eval $cmd || error "mds-survey with stripe_count failed"
21866         cat ${TMP}/mds_survey*
21867         rm -f ${TMP}/mds_survey*
21868 }
21869 run_test 225b "Metadata survey sanity with stripe_count = 1"
21870
21871 mcreate_path2fid () {
21872         local mode=$1
21873         local major=$2
21874         local minor=$3
21875         local name=$4
21876         local desc=$5
21877         local path=$DIR/$tdir/$name
21878         local fid
21879         local rc
21880         local fid_path
21881
21882         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21883                 error "cannot create $desc"
21884
21885         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21886         rc=$?
21887         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21888
21889         fid_path=$($LFS fid2path $MOUNT $fid)
21890         rc=$?
21891         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21892
21893         [ "$path" == "$fid_path" ] ||
21894                 error "fid2path returned $fid_path, expected $path"
21895
21896         echo "pass with $path and $fid"
21897 }
21898
21899 test_226a () {
21900         rm -rf $DIR/$tdir
21901         mkdir -p $DIR/$tdir
21902
21903         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21904         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21905         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21906         mcreate_path2fid 0040666 0 0 dir "directory"
21907         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21908         mcreate_path2fid 0100666 0 0 file "regular file"
21909         mcreate_path2fid 0120666 0 0 link "symbolic link"
21910         mcreate_path2fid 0140666 0 0 sock "socket"
21911 }
21912 run_test 226a "call path2fid and fid2path on files of all type"
21913
21914 test_226b () {
21915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21916
21917         local MDTIDX=1
21918
21919         rm -rf $DIR/$tdir
21920         mkdir -p $DIR/$tdir
21921         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21922                 error "create remote directory failed"
21923         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21924         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21925                                 "character special file (null)"
21926         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21927                                 "character special file (no device)"
21928         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21929         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21930                                 "block special file (loop)"
21931         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21932         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21933         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21934 }
21935 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21936
21937 test_226c () {
21938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21939         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21940                 skip "Need MDS version at least 2.13.55"
21941
21942         local submnt=/mnt/submnt
21943         local srcfile=/etc/passwd
21944         local dstfile=$submnt/passwd
21945         local path
21946         local fid
21947
21948         rm -rf $DIR/$tdir
21949         rm -rf $submnt
21950         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21951                 error "create remote directory failed"
21952         mkdir -p $submnt || error "create $submnt failed"
21953         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21954                 error "mount $submnt failed"
21955         stack_trap "umount $submnt" EXIT
21956
21957         cp $srcfile $dstfile
21958         fid=$($LFS path2fid $dstfile)
21959         path=$($LFS fid2path $submnt "$fid")
21960         [ "$path" = "$dstfile" ] ||
21961                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21962 }
21963 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21964
21965 test_226d () {
21966         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21967                 skip "Need client at least version 2.15.57"
21968
21969         # Define First test dataset
21970         local testdirs_01=$DIR/$tdir
21971         local testdata_01=$testdirs_01/${tdir}_01
21972         local testresult_01=${tdir}_01
21973         # Define Second test dataset
21974         local testdirs_02=$DIR/$tdir/$tdir
21975         local testdata_02=$testdirs_02/${tdir}_02
21976         local testresult_02=${tdir}_02
21977         # Define third test dataset (top level)
21978         local testdata_03=$DIR/${tdir}_03
21979         local testresult_03=${tdir}_03
21980
21981         # Create first test dataset
21982         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21983         touch $testdata_01 || error "cannot create file $testdata_01"
21984
21985         # Create second test dataset
21986         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21987         touch $testdata_02 || error "cannot create file $testdata_02"
21988
21989         # Create third test dataset
21990         touch $testdata_03 || error "cannot create file $testdata_03"
21991
21992         local fid01=$($LFS getstripe -F "$testdata_01") ||
21993                 error "getstripe failed on $testdata_01"
21994         local fid02=$($LFS getstripe -F "$testdata_02") ||
21995                 error "getstripe failed on $testdata_01"
21996         local fid03=$($LFS getstripe -F "$testdata_03") ||
21997                 error "getstripe failed on $testdata_03"
21998
21999         # Verify only -n option
22000         local out1=$($LFS fid2path -n $DIR $fid01) ||
22001                 error "fid2path failed on $fid01"
22002         local out2=$($LFS fid2path -n $DIR $fid02) ||
22003                 error "fid2path failed on $fid02"
22004         local out3=$($LFS fid2path -n $DIR $fid03) ||
22005                 error "fid2path failed on $fid03"
22006
22007         [[ "$out1" == "$testresult_01" ]] ||
22008                 error "fid2path failed: Expected $testresult_01 got $out1"
22009         [[ "$out2" == "$testresult_02" ]] ||
22010                 error "fid2path failed: Expected $testresult_02 got $out2"
22011         [[ "$out3" == "$testresult_03" ]] ||
22012                 error "fid2path failed: Expected $testresult_03 got $out3"
22013
22014         # Verify with option -fn together
22015         out1=$($LFS fid2path -fn $DIR $fid01) ||
22016                 error "fid2path -fn failed on $fid01"
22017         out2=$($LFS fid2path -fn $DIR $fid02) ||
22018                 error "fid2path -fn failed on $fid02"
22019         out3=$($LFS fid2path -fn $DIR $fid03) ||
22020                 error "fid2path -fn failed on $fid03"
22021
22022         local tmpout=$(echo $out1 | cut -d" " -f2)
22023         [[ "$tmpout" == "$testresult_01" ]] ||
22024                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
22025
22026         tmpout=$(echo $out2 | cut -d" " -f2)
22027         [[ "$tmpout" == "$testresult_02" ]] ||
22028                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
22029
22030         tmpout=$(echo $out3 | cut -d" " -f2)
22031         [[ "$tmpout" == "$testresult_03" ]] ||
22032                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
22033 }
22034 run_test 226d "verify fid2path with -n and -fn option"
22035
22036 test_226e () {
22037         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
22038                 skip "Need client at least version 2.15.56"
22039
22040         # Define filename with 'newline' and a space
22041         local testfile="Test"$'\n'"file 01"
22042         # Define link name with multiple 'newline' and a space
22043         local linkfile="Link"$'\n'"file "$'\n'"01"
22044         # Remove prior hard link
22045         rm -f $DIR/"$linkfile"
22046
22047         # Create file
22048         touch $DIR/"$testfile"
22049         # Create link
22050         ln $DIR/"$testfile" $DIR/"$linkfile"
22051
22052         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
22053                 error "getstripe failed on $DIR/$testfile"
22054
22055         # Call with -0 option
22056         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
22057                 echo "FILE:" | grep -c "FILE:")
22058
22059         # With -0 option the output should be exactly 2 lines.
22060         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
22061 }
22062 run_test 226e "Verify path2fid -0 option with newline and space"
22063
22064 # LU-1299 Executing or running ldd on a truncated executable does not
22065 # cause an out-of-memory condition.
22066 test_227() {
22067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22068         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
22069
22070         dd if=$(which date) of=$MOUNT/date bs=1k count=1
22071         chmod +x $MOUNT/date
22072
22073         $MOUNT/date > /dev/null
22074         ldd $MOUNT/date > /dev/null
22075         rm -f $MOUNT/date
22076 }
22077 run_test 227 "running truncated executable does not cause OOM"
22078
22079 # LU-1512 try to reuse idle OI blocks
22080 test_228a() {
22081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22082         remote_mds_nodsh && skip "remote MDS with nodsh"
22083         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22084
22085         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22086         local myDIR=$DIR/$tdir
22087
22088         mkdir -p $myDIR
22089         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22090         $LCTL set_param fail_loc=0x80001002
22091         createmany -o $myDIR/t- 10000
22092         $LCTL set_param fail_loc=0
22093         # The guard is current the largest FID holder
22094         touch $myDIR/guard
22095         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22096                     tr -d '[')
22097         local IDX=$(($SEQ % 64))
22098
22099         do_facet $SINGLEMDS sync
22100         # Make sure journal flushed.
22101         sleep 6
22102         local blk1=$(do_facet $SINGLEMDS \
22103                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22104                      grep Blockcount | awk '{print $4}')
22105
22106         # Remove old files, some OI blocks will become idle.
22107         unlinkmany $myDIR/t- 10000
22108         # Create new files, idle OI blocks should be reused.
22109         createmany -o $myDIR/t- 2000
22110         do_facet $SINGLEMDS sync
22111         # Make sure journal flushed.
22112         sleep 6
22113         local blk2=$(do_facet $SINGLEMDS \
22114                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22115                      grep Blockcount | awk '{print $4}')
22116
22117         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22118 }
22119 run_test 228a "try to reuse idle OI blocks"
22120
22121 test_228b() {
22122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22123         remote_mds_nodsh && skip "remote MDS with nodsh"
22124         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22125
22126         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22127         local myDIR=$DIR/$tdir
22128
22129         mkdir -p $myDIR
22130         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22131         $LCTL set_param fail_loc=0x80001002
22132         createmany -o $myDIR/t- 10000
22133         $LCTL set_param fail_loc=0
22134         # The guard is current the largest FID holder
22135         touch $myDIR/guard
22136         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22137                     tr -d '[')
22138         local IDX=$(($SEQ % 64))
22139
22140         do_facet $SINGLEMDS sync
22141         # Make sure journal flushed.
22142         sleep 6
22143         local blk1=$(do_facet $SINGLEMDS \
22144                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22145                      grep Blockcount | awk '{print $4}')
22146
22147         # Remove old files, some OI blocks will become idle.
22148         unlinkmany $myDIR/t- 10000
22149
22150         # stop the MDT
22151         stop $SINGLEMDS || error "Fail to stop MDT."
22152         # remount the MDT
22153         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
22154                 error "Fail to start MDT."
22155
22156         client_up || error "Fail to df."
22157         # Create new files, idle OI blocks should be reused.
22158         createmany -o $myDIR/t- 2000
22159         do_facet $SINGLEMDS sync
22160         # Make sure journal flushed.
22161         sleep 6
22162         local blk2=$(do_facet $SINGLEMDS \
22163                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22164                      grep Blockcount | awk '{print $4}')
22165
22166         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22167 }
22168 run_test 228b "idle OI blocks can be reused after MDT restart"
22169
22170 #LU-1881
22171 test_228c() {
22172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22173         remote_mds_nodsh && skip "remote MDS with nodsh"
22174         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22175
22176         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22177         local myDIR=$DIR/$tdir
22178
22179         mkdir -p $myDIR
22180         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22181         $LCTL set_param fail_loc=0x80001002
22182         # 20000 files can guarantee there are index nodes in the OI file
22183         createmany -o $myDIR/t- 20000
22184         $LCTL set_param fail_loc=0
22185         # The guard is current the largest FID holder
22186         touch $myDIR/guard
22187         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22188                     tr -d '[')
22189         local IDX=$(($SEQ % 64))
22190
22191         do_facet $SINGLEMDS sync
22192         # Make sure journal flushed.
22193         sleep 6
22194         local blk1=$(do_facet $SINGLEMDS \
22195                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22196                      grep Blockcount | awk '{print $4}')
22197
22198         # Remove old files, some OI blocks will become idle.
22199         unlinkmany $myDIR/t- 20000
22200         rm -f $myDIR/guard
22201         # The OI file should become empty now
22202
22203         # Create new files, idle OI blocks should be reused.
22204         createmany -o $myDIR/t- 2000
22205         do_facet $SINGLEMDS sync
22206         # Make sure journal flushed.
22207         sleep 6
22208         local blk2=$(do_facet $SINGLEMDS \
22209                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22210                      grep Blockcount | awk '{print $4}')
22211
22212         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22213 }
22214 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22215
22216 test_229() { # LU-2482, LU-3448
22217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22218         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22219         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22220                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22221
22222         rm -f $DIR/$tfile
22223
22224         # Create a file with a released layout and stripe count 2.
22225         $MULTIOP $DIR/$tfile H2c ||
22226                 error "failed to create file with released layout"
22227
22228         $LFS getstripe -v $DIR/$tfile
22229
22230         local pattern=$($LFS getstripe -L $DIR/$tfile)
22231         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22232
22233         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22234                 error "getstripe"
22235         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22236         stat $DIR/$tfile || error "failed to stat released file"
22237
22238         chown $RUNAS_ID $DIR/$tfile ||
22239                 error "chown $RUNAS_ID $DIR/$tfile failed"
22240
22241         chgrp $RUNAS_ID $DIR/$tfile ||
22242                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22243
22244         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22245         rm $DIR/$tfile || error "failed to remove released file"
22246 }
22247 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22248
22249 test_230a() {
22250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22251         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22252         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22253                 skip "Need MDS version at least 2.11.52"
22254
22255         local MDTIDX=1
22256
22257         test_mkdir $DIR/$tdir
22258         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22259         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22260         [ $mdt_idx -ne 0 ] &&
22261                 error "create local directory on wrong MDT $mdt_idx"
22262
22263         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22264                         error "create remote directory failed"
22265         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22266         [ $mdt_idx -ne $MDTIDX ] &&
22267                 error "create remote directory on wrong MDT $mdt_idx"
22268
22269         createmany -o $DIR/$tdir/test_230/t- 10 ||
22270                 error "create files on remote directory failed"
22271         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22272         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22273         rm -r $DIR/$tdir || error "unlink remote directory failed"
22274 }
22275 run_test 230a "Create remote directory and files under the remote directory"
22276
22277 test_230b() {
22278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22279         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22281                 skip "Need MDS version at least 2.11.52"
22282
22283         local MDTIDX=1
22284         local mdt_index
22285         local i
22286         local file
22287         local pid
22288         local stripe_count
22289         local migrate_dir=$DIR/$tdir/migrate_dir
22290         local other_dir=$DIR/$tdir/other_dir
22291
22292         test_mkdir $DIR/$tdir
22293         test_mkdir -i0 -c1 $migrate_dir
22294         test_mkdir -i0 -c1 $other_dir
22295         for ((i=0; i<10; i++)); do
22296                 mkdir -p $migrate_dir/dir_${i}
22297                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22298                         error "create files under remote dir failed $i"
22299         done
22300
22301         cp /etc/passwd $migrate_dir/$tfile
22302         cp /etc/passwd $other_dir/$tfile
22303         chattr +SAD $migrate_dir
22304         chattr +SAD $migrate_dir/$tfile
22305
22306         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22307         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22308         local old_dir_mode=$(stat -c%f $migrate_dir)
22309         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22310
22311         mkdir -p $migrate_dir/dir_default_stripe2
22312         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22313         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22314
22315         mkdir -p $other_dir
22316         ln $migrate_dir/$tfile $other_dir/luna
22317         ln $migrate_dir/$tfile $migrate_dir/sofia
22318         ln $other_dir/$tfile $migrate_dir/david
22319         ln -s $migrate_dir/$tfile $other_dir/zachary
22320         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22321         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22322
22323         local len
22324         local lnktgt
22325
22326         # inline symlink
22327         for len in 58 59 60; do
22328                 lnktgt=$(str_repeat 'l' $len)
22329                 touch $migrate_dir/$lnktgt
22330                 ln -s $lnktgt $migrate_dir/${len}char_ln
22331         done
22332
22333         # PATH_MAX
22334         for len in 4094 4095; do
22335                 lnktgt=$(str_repeat 'l' $len)
22336                 ln -s $lnktgt $migrate_dir/${len}char_ln
22337         done
22338
22339         # NAME_MAX
22340         for len in 254 255; do
22341                 touch $migrate_dir/$(str_repeat 'l' $len)
22342         done
22343
22344         $LFS migrate -m $MDTIDX $migrate_dir ||
22345                 error "fails on migrating remote dir to MDT1"
22346
22347         echo "migratate to MDT1, then checking.."
22348         for ((i = 0; i < 10; i++)); do
22349                 for file in $(find $migrate_dir/dir_${i}); do
22350                         mdt_index=$($LFS getstripe -m $file)
22351                         # broken symlink getstripe will fail
22352                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22353                                 error "$file is not on MDT${MDTIDX}"
22354                 done
22355         done
22356
22357         # the multiple link file should still in MDT0
22358         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22359         [ $mdt_index == 0 ] ||
22360                 error "$file is not on MDT${MDTIDX}"
22361
22362         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22363         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22364                 error " expect $old_dir_flag get $new_dir_flag"
22365
22366         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22367         [ "$old_file_flag" = "$new_file_flag" ] ||
22368                 error " expect $old_file_flag get $new_file_flag"
22369
22370         local new_dir_mode=$(stat -c%f $migrate_dir)
22371         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22372                 error "expect mode $old_dir_mode get $new_dir_mode"
22373
22374         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22375         [ "$old_file_mode" = "$new_file_mode" ] ||
22376                 error "expect mode $old_file_mode get $new_file_mode"
22377
22378         diff /etc/passwd $migrate_dir/$tfile ||
22379                 error "$tfile different after migration"
22380
22381         diff /etc/passwd $other_dir/luna ||
22382                 error "luna different after migration"
22383
22384         diff /etc/passwd $migrate_dir/sofia ||
22385                 error "sofia different after migration"
22386
22387         diff /etc/passwd $migrate_dir/david ||
22388                 error "david different after migration"
22389
22390         diff /etc/passwd $other_dir/zachary ||
22391                 error "zachary different after migration"
22392
22393         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22394                 error "${tfile}_ln different after migration"
22395
22396         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22397                 error "${tfile}_ln_other different after migration"
22398
22399         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22400         [ $stripe_count = 2 ] ||
22401                 error "dir strpe_count $d != 2 after migration."
22402
22403         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22404         [ $stripe_count = 2 ] ||
22405                 error "file strpe_count $d != 2 after migration."
22406
22407         #migrate back to MDT0
22408         MDTIDX=0
22409
22410         $LFS migrate -m $MDTIDX $migrate_dir ||
22411                 error "fails on migrating remote dir to MDT0"
22412
22413         echo "migrate back to MDT0, checking.."
22414         for file in $(find $migrate_dir); do
22415                 mdt_index=$($LFS getstripe -m $file)
22416                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22417                         error "$file is not on MDT${MDTIDX}"
22418         done
22419
22420         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22421         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22422                 error " expect $old_dir_flag get $new_dir_flag"
22423
22424         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22425         [ "$old_file_flag" = "$new_file_flag" ] ||
22426                 error " expect $old_file_flag get $new_file_flag"
22427
22428         local new_dir_mode=$(stat -c%f $migrate_dir)
22429         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22430                 error "expect mode $old_dir_mode get $new_dir_mode"
22431
22432         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22433         [ "$old_file_mode" = "$new_file_mode" ] ||
22434                 error "expect mode $old_file_mode get $new_file_mode"
22435
22436         diff /etc/passwd ${migrate_dir}/$tfile ||
22437                 error "$tfile different after migration"
22438
22439         diff /etc/passwd ${other_dir}/luna ||
22440                 error "luna different after migration"
22441
22442         diff /etc/passwd ${migrate_dir}/sofia ||
22443                 error "sofia different after migration"
22444
22445         diff /etc/passwd ${other_dir}/zachary ||
22446                 error "zachary different after migration"
22447
22448         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22449                 error "${tfile}_ln different after migration"
22450
22451         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22452                 error "${tfile}_ln_other different after migration"
22453
22454         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22455         [ $stripe_count = 2 ] ||
22456                 error "dir strpe_count $d != 2 after migration."
22457
22458         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22459         [ $stripe_count = 2 ] ||
22460                 error "file strpe_count $d != 2 after migration."
22461
22462         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22463 }
22464 run_test 230b "migrate directory"
22465
22466 test_230c() {
22467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22468         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22469         remote_mds_nodsh && skip "remote MDS with nodsh"
22470         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22471                 skip "Need MDS version at least 2.11.52"
22472
22473         local MDTIDX=1
22474         local total=3
22475         local mdt_index
22476         local file
22477         local migrate_dir=$DIR/$tdir/migrate_dir
22478
22479         #If migrating directory fails in the middle, all entries of
22480         #the directory is still accessiable.
22481         test_mkdir $DIR/$tdir
22482         test_mkdir -i0 -c1 $migrate_dir
22483         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22484         stat $migrate_dir
22485         createmany -o $migrate_dir/f $total ||
22486                 error "create files under ${migrate_dir} failed"
22487
22488         # fail after migrating top dir, and this will fail only once, so the
22489         # first sub file migration will fail (currently f3), others succeed.
22490         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22491         do_facet mds1 lctl set_param fail_loc=0x1801
22492         local t=$(ls $migrate_dir | wc -l)
22493         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22494                 error "migrate should fail"
22495         local u=$(ls $migrate_dir | wc -l)
22496         [ "$u" == "$t" ] || error "$u != $t during migration"
22497
22498         # add new dir/file should succeed
22499         mkdir $migrate_dir/dir ||
22500                 error "mkdir failed under migrating directory"
22501         touch $migrate_dir/file ||
22502                 error "create file failed under migrating directory"
22503
22504         # add file with existing name should fail
22505         for file in $migrate_dir/f*; do
22506                 stat $file > /dev/null || error "stat $file failed"
22507                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22508                         error "open(O_CREAT|O_EXCL) $file should fail"
22509                 $MULTIOP $file m && error "create $file should fail"
22510                 touch $DIR/$tdir/remote_dir/$tfile ||
22511                         error "touch $tfile failed"
22512                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22513                         error "link $file should fail"
22514                 mdt_index=$($LFS getstripe -m $file)
22515                 if [ $mdt_index == 0 ]; then
22516                         # file failed to migrate is not allowed to rename to
22517                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22518                                 error "rename to $file should fail"
22519                 else
22520                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22521                                 error "rename to $file failed"
22522                 fi
22523                 echo hello >> $file || error "write $file failed"
22524         done
22525
22526         # resume migration with different options should fail
22527         $LFS migrate -m 0 $migrate_dir &&
22528                 error "migrate -m 0 $migrate_dir should fail"
22529
22530         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22531                 error "migrate -c 2 $migrate_dir should fail"
22532
22533         # resume migration should succeed
22534         $LFS migrate -m $MDTIDX $migrate_dir ||
22535                 error "migrate $migrate_dir failed"
22536
22537         echo "Finish migration, then checking.."
22538         for file in $(find $migrate_dir); do
22539                 mdt_index=$($LFS getstripe -m $file)
22540                 [ $mdt_index == $MDTIDX ] ||
22541                         error "$file is not on MDT${MDTIDX}"
22542         done
22543
22544         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22545 }
22546 run_test 230c "check directory accessiblity if migration failed"
22547
22548 test_230d() {
22549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22550         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22551         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22552                 skip "Need MDS version at least 2.11.52"
22553         # LU-11235
22554         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22555
22556         local migrate_dir=$DIR/$tdir/migrate_dir
22557         local old_index
22558         local new_index
22559         local old_count
22560         local new_count
22561         local new_hash
22562         local mdt_index
22563         local i
22564         local j
22565
22566         old_index=$((RANDOM % MDSCOUNT))
22567         old_count=$((MDSCOUNT - old_index))
22568         new_index=$((RANDOM % MDSCOUNT))
22569         new_count=$((MDSCOUNT - new_index))
22570         new_hash=1 # for all_char
22571
22572         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22573         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22574
22575         test_mkdir $DIR/$tdir
22576         test_mkdir -i $old_index -c $old_count $migrate_dir
22577
22578         for ((i=0; i<100; i++)); do
22579                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22580                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22581                         error "create files under remote dir failed $i"
22582         done
22583
22584         echo -n "Migrate from MDT$old_index "
22585         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22586         echo -n "to MDT$new_index"
22587         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22588         echo
22589
22590         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22591         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22592                 error "migrate remote dir error"
22593
22594         echo "Finish migration, then checking.."
22595         for file in $(find $migrate_dir -maxdepth 1); do
22596                 mdt_index=$($LFS getstripe -m $file)
22597                 if [ $mdt_index -lt $new_index ] ||
22598                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22599                         error "$file is on MDT$mdt_index"
22600                 fi
22601         done
22602
22603         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22604 }
22605 run_test 230d "check migrate big directory"
22606
22607 test_230e() {
22608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22609         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22610         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22611                 skip "Need MDS version at least 2.11.52"
22612
22613         local i
22614         local j
22615         local a_fid
22616         local b_fid
22617
22618         mkdir_on_mdt0 $DIR/$tdir
22619         mkdir $DIR/$tdir/migrate_dir
22620         mkdir $DIR/$tdir/other_dir
22621         touch $DIR/$tdir/migrate_dir/a
22622         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22623         ls $DIR/$tdir/other_dir
22624
22625         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22626                 error "migrate dir fails"
22627
22628         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22629         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22630
22631         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22632         [ $mdt_index == 0 ] || error "a is not on MDT0"
22633
22634         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22635                 error "migrate dir fails"
22636
22637         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22638         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22639
22640         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22641         [ $mdt_index == 1 ] || error "a is not on MDT1"
22642
22643         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22644         [ $mdt_index == 1 ] || error "b is not on MDT1"
22645
22646         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22647         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22648
22649         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22650
22651         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22652 }
22653 run_test 230e "migrate mulitple local link files"
22654
22655 test_230f() {
22656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22657         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22658         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22659                 skip "Need MDS version at least 2.11.52"
22660
22661         local a_fid
22662         local ln_fid
22663
22664         mkdir -p $DIR/$tdir
22665         mkdir $DIR/$tdir/migrate_dir
22666         $LFS mkdir -i1 $DIR/$tdir/other_dir
22667         touch $DIR/$tdir/migrate_dir/a
22668         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22669         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22670         ls $DIR/$tdir/other_dir
22671
22672         # a should be migrated to MDT1, since no other links on MDT0
22673         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22674                 error "#1 migrate dir fails"
22675         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22676         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22677         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22678         [ $mdt_index == 1 ] || error "a is not on MDT1"
22679
22680         # a should stay on MDT1, because it is a mulitple link file
22681         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22682                 error "#2 migrate dir fails"
22683         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22684         [ $mdt_index == 1 ] || error "a is not on MDT1"
22685
22686         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22687                 error "#3 migrate dir fails"
22688
22689         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22690         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22691         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22692
22693         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22694         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22695
22696         # a should be migrated to MDT0, since no other links on MDT1
22697         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22698                 error "#4 migrate dir fails"
22699         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22700         [ $mdt_index == 0 ] || error "a is not on MDT0"
22701
22702         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22703 }
22704 run_test 230f "migrate mulitple remote link files"
22705
22706 test_230g() {
22707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22709         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22710                 skip "Need MDS version at least 2.11.52"
22711
22712         mkdir -p $DIR/$tdir/migrate_dir
22713
22714         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22715                 error "migrating dir to non-exist MDT succeeds"
22716         true
22717 }
22718 run_test 230g "migrate dir to non-exist MDT"
22719
22720 test_230h() {
22721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22722         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22723         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22724                 skip "Need MDS version at least 2.11.52"
22725
22726         local mdt_index
22727
22728         mkdir -p $DIR/$tdir/migrate_dir
22729
22730         $LFS migrate -m1 $DIR &&
22731                 error "migrating mountpoint1 should fail"
22732
22733         $LFS migrate -m1 $DIR/$tdir/.. &&
22734                 error "migrating mountpoint2 should fail"
22735
22736         # same as mv
22737         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22738                 error "migrating $tdir/migrate_dir/.. should fail"
22739
22740         true
22741 }
22742 run_test 230h "migrate .. and root"
22743
22744 test_230i() {
22745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22747         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22748                 skip "Need MDS version at least 2.11.52"
22749
22750         mkdir -p $DIR/$tdir/migrate_dir
22751
22752         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22753                 error "migration fails with a tailing slash"
22754
22755         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22756                 error "migration fails with two tailing slashes"
22757 }
22758 run_test 230i "lfs migrate -m tolerates trailing slashes"
22759
22760 test_230j() {
22761         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22762         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22763                 skip "Need MDS version at least 2.11.52"
22764
22765         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22766         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22767                 error "create $tfile failed"
22768         cat /etc/passwd > $DIR/$tdir/$tfile
22769
22770         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22771
22772         cmp /etc/passwd $DIR/$tdir/$tfile ||
22773                 error "DoM file mismatch after migration"
22774 }
22775 run_test 230j "DoM file data not changed after dir migration"
22776
22777 test_230k() {
22778         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22779         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22780                 skip "Need MDS version at least 2.11.56"
22781
22782         local total=20
22783         local files_on_starting_mdt=0
22784
22785         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22786         $LFS getdirstripe $DIR/$tdir
22787         for i in $(seq $total); do
22788                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22789                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22790                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22791         done
22792
22793         echo "$files_on_starting_mdt files on MDT0"
22794
22795         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22796         $LFS getdirstripe $DIR/$tdir
22797
22798         files_on_starting_mdt=0
22799         for i in $(seq $total); do
22800                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22801                         error "file $tfile.$i mismatch after migration"
22802                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22803                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22804         done
22805
22806         echo "$files_on_starting_mdt files on MDT1 after migration"
22807         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22808
22809         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22810         $LFS getdirstripe $DIR/$tdir
22811
22812         files_on_starting_mdt=0
22813         for i in $(seq $total); do
22814                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22815                         error "file $tfile.$i mismatch after 2nd migration"
22816                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22817                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22818         done
22819
22820         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22821         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22822
22823         true
22824 }
22825 run_test 230k "file data not changed after dir migration"
22826
22827 test_230l() {
22828         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22829         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22830                 skip "Need MDS version at least 2.11.56"
22831
22832         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22833         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22834                 error "create files under remote dir failed $i"
22835         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22836 }
22837 run_test 230l "readdir between MDTs won't crash"
22838
22839 test_230m() {
22840         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22841         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22842                 skip "Need MDS version at least 2.11.56"
22843
22844         local MDTIDX=1
22845         local mig_dir=$DIR/$tdir/migrate_dir
22846         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22847         local shortstr="b"
22848         local val
22849
22850         echo "Creating files and dirs with xattrs"
22851         test_mkdir $DIR/$tdir
22852         test_mkdir -i0 -c1 $mig_dir
22853         mkdir $mig_dir/dir
22854         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22855                 error "cannot set xattr attr1 on dir"
22856         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22857                 error "cannot set xattr attr2 on dir"
22858         touch $mig_dir/dir/f0
22859         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22860                 error "cannot set xattr attr1 on file"
22861         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22862                 error "cannot set xattr attr2 on file"
22863         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22864         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22865         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22866         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22867         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22868         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22869         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22870         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22871         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22872
22873         echo "Migrating to MDT1"
22874         $LFS migrate -m $MDTIDX $mig_dir ||
22875                 error "fails on migrating dir to MDT1"
22876
22877         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22878         echo "Checking xattrs"
22879         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22880         [ "$val" = $longstr ] ||
22881                 error "expecting xattr1 $longstr on dir, found $val"
22882         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22883         [ "$val" = $shortstr ] ||
22884                 error "expecting xattr2 $shortstr on dir, found $val"
22885         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22886         [ "$val" = $longstr ] ||
22887                 error "expecting xattr1 $longstr on file, found $val"
22888         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22889         [ "$val" = $shortstr ] ||
22890                 error "expecting xattr2 $shortstr on file, found $val"
22891 }
22892 run_test 230m "xattrs not changed after dir migration"
22893
22894 test_230n() {
22895         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22896         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22897                 skip "Need MDS version at least 2.13.53"
22898
22899         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22900         cat /etc/hosts > $DIR/$tdir/$tfile
22901         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22902         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22903
22904         cmp /etc/hosts $DIR/$tdir/$tfile ||
22905                 error "File data mismatch after migration"
22906 }
22907 run_test 230n "Dir migration with mirrored file"
22908
22909 test_230o() {
22910         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22911         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22912                 skip "Need MDS version at least 2.13.52"
22913
22914         local mdts=$(comma_list $(mdts_nodes))
22915         local timeout=100
22916         local restripe_status
22917         local delta
22918         local i
22919
22920         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22921
22922         # in case "crush" hash type is not set
22923         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22924
22925         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22926                            mdt.*MDT0000.enable_dir_restripe)
22927         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22928         stack_trap "do_nodes $mdts $LCTL set_param \
22929                     mdt.*.enable_dir_restripe=$restripe_status"
22930
22931         mkdir $DIR/$tdir
22932         createmany -m $DIR/$tdir/f 100 ||
22933                 error "create files under remote dir failed $i"
22934         createmany -d $DIR/$tdir/d 100 ||
22935                 error "create dirs under remote dir failed $i"
22936
22937         for i in $(seq 2 $MDSCOUNT); do
22938                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22939                 $LFS setdirstripe -c $i $DIR/$tdir ||
22940                         error "split -c $i $tdir failed"
22941                 wait_update $HOSTNAME \
22942                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22943                         error "dir split not finished"
22944                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22945                         awk '/migrate/ {sum += $2} END { print sum }')
22946                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22947                 # delta is around total_files/stripe_count
22948                 (( $delta < 200 / (i - 1) + 4 )) ||
22949                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22950         done
22951 }
22952 run_test 230o "dir split"
22953
22954 test_230p() {
22955         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22956         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22957                 skip "Need MDS version at least 2.13.52"
22958
22959         local mdts=$(comma_list $(mdts_nodes))
22960         local timeout=100
22961         local restripe_status
22962         local delta
22963         local c
22964
22965         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22966
22967         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22968
22969         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22970                            mdt.*MDT0000.enable_dir_restripe)
22971         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22972         stack_trap "do_nodes $mdts $LCTL set_param \
22973                     mdt.*.enable_dir_restripe=$restripe_status"
22974
22975         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22976         createmany -m $DIR/$tdir/f 100 ||
22977                 error "create files under remote dir failed"
22978         createmany -d $DIR/$tdir/d 100 ||
22979                 error "create dirs under remote dir failed"
22980
22981         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22982                 local mdt_hash="crush"
22983
22984                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22985                 $LFS setdirstripe -c $c $DIR/$tdir ||
22986                         error "split -c $c $tdir failed"
22987                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22988                         mdt_hash="$mdt_hash,fixed"
22989                 elif [ $c -eq 1 ]; then
22990                         mdt_hash="none"
22991                 fi
22992                 wait_update $HOSTNAME \
22993                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22994                         error "dir merge not finished"
22995                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22996                         awk '/migrate/ {sum += $2} END { print sum }')
22997                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22998                 # delta is around total_files/stripe_count
22999                 (( delta < 200 / c + 4 )) ||
23000                         error "$delta files migrated >= $((200 / c + 4))"
23001         done
23002 }
23003 run_test 230p "dir merge"
23004
23005 test_230q() {
23006         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
23007         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
23008                 skip "Need MDS version at least 2.13.52"
23009
23010         local mdts=$(comma_list $(mdts_nodes))
23011         local saved_threshold=$(do_facet mds1 \
23012                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
23013         local saved_delta=$(do_facet mds1 \
23014                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
23015         local threshold=100
23016         local delta=2
23017         local total=0
23018         local stripe_count=0
23019         local stripe_index
23020         local nr_files
23021         local create
23022
23023         # test with fewer files on ZFS
23024         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
23025
23026         stack_trap "do_nodes $mdts $LCTL set_param \
23027                     mdt.*.dir_split_count=$saved_threshold"
23028         stack_trap "do_nodes $mdts $LCTL set_param \
23029                     mdt.*.dir_split_delta=$saved_delta"
23030         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
23031         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
23032         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
23033         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
23034         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
23035         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
23036
23037         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
23038         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23039
23040         create=$((threshold * 3 / 2))
23041         while [ $stripe_count -lt $MDSCOUNT ]; do
23042                 createmany -m $DIR/$tdir/f $total $create ||
23043                         error "create sub files failed"
23044                 stat $DIR/$tdir > /dev/null
23045                 total=$((total + create))
23046                 stripe_count=$((stripe_count + delta))
23047                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
23048
23049                 wait_update $HOSTNAME \
23050                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
23051                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
23052
23053                 wait_update $HOSTNAME \
23054                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
23055                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
23056
23057                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
23058                 echo "$nr_files/$total files on MDT$stripe_index after split"
23059                 # allow 10% margin of imbalance with crush hash
23060                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
23061                         error "$nr_files files on MDT$stripe_index after split"
23062
23063                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
23064                 [ $nr_files -eq $total ] ||
23065                         error "total sub files $nr_files != $total"
23066         done
23067
23068         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
23069
23070         echo "fixed layout directory won't auto split"
23071         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
23072         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
23073                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
23074         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
23075                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
23076 }
23077 run_test 230q "dir auto split"
23078
23079 test_230r() {
23080         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
23081         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
23082         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
23083                 skip "Need MDS version at least 2.13.54"
23084
23085         # maximum amount of local locks:
23086         # parent striped dir - 2 locks
23087         # new stripe in parent to migrate to - 1 lock
23088         # source and target - 2 locks
23089         # Total 5 locks for regular file
23090         mkdir -p $DIR/$tdir
23091         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
23092         touch $DIR/$tdir/dir1/eee
23093
23094         # create 4 hardlink for 4 more locks
23095         # Total: 9 locks > RS_MAX_LOCKS (8)
23096         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
23097         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
23098         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
23099         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
23100         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
23101         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
23102         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
23103         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
23104
23105         cancel_lru_locks mdc
23106
23107         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
23108                 error "migrate dir fails"
23109
23110         rm -rf $DIR/$tdir || error "rm dir failed after migration"
23111 }
23112 run_test 230r "migrate with too many local locks"
23113
23114 test_230s() {
23115         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
23116                 skip "Need MDS version at least 2.14.52"
23117
23118         local mdts=$(comma_list $(mdts_nodes))
23119         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
23120                                 mdt.*MDT0000.enable_dir_restripe)
23121
23122         stack_trap "do_nodes $mdts $LCTL set_param \
23123                     mdt.*.enable_dir_restripe=$restripe_status"
23124
23125         local st
23126         for st in 0 1; do
23127                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
23128                 test_mkdir $DIR/$tdir
23129                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
23130                         error "$LFS mkdir should return EEXIST if target exists"
23131                 rmdir $DIR/$tdir
23132         done
23133 }
23134 run_test 230s "lfs mkdir should return -EEXIST if target exists"
23135
23136 test_230t()
23137 {
23138         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
23139         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
23140                 skip "Need MDS version at least 2.14.50"
23141
23142         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
23143         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
23144         $LFS project -p 1 -s $DIR/$tdir ||
23145                 error "set $tdir project id failed"
23146         $LFS project -p 2 -s $DIR/$tdir/subdir ||
23147                 error "set subdir project id failed"
23148         local pbefore="$($LFS project -d $DIR/$tdir)"
23149         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
23150         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
23151
23152         local pafter="$($LFS project -d $DIR/$tdir)"
23153         local safter="$($LFS project -d $DIR/$tdir/subdir)"
23154         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
23155         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
23156
23157         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
23158                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
23159
23160         # check rename works, even if source parent projid differs (LU-17016)
23161         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
23162         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
23163
23164         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
23165         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
23166                 error "subdir failed rename for different source parent projid"
23167         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
23168
23169         [[ "$fid_before" == "$fid_after" ]] ||
23170                 error "fid before '$fid_before' != after '$fid_after'"
23171 }
23172 run_test 230t "migrate directory with project ID set"
23173
23174 test_230u()
23175 {
23176         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23177         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23178                 skip "Need MDS version at least 2.14.53"
23179
23180         local count
23181
23182         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23183         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23184         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
23185         for i in $(seq 0 $((MDSCOUNT - 1))); do
23186                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23187                 echo "$count dirs migrated to MDT$i"
23188         done
23189         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23190         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
23191 }
23192 run_test 230u "migrate directory by QOS"
23193
23194 test_230v()
23195 {
23196         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23197         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23198                 skip "Need MDS version at least 2.14.53"
23199
23200         local count
23201
23202         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23203         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23204         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23205         for i in $(seq 0 $((MDSCOUNT - 1))); do
23206                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23207                 echo "$count subdirs migrated to MDT$i"
23208                 (( i == 3 )) && (( count > 0 )) &&
23209                         error "subdir shouldn't be migrated to MDT3"
23210         done
23211         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23212         (( count == 3 )) || error "dirs migrated to $count MDTs"
23213 }
23214 run_test 230v "subdir migrated to the MDT where its parent is located"
23215
23216 test_230w() {
23217         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23218         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23219                 skip "Need MDS version at least 2.15.0"
23220
23221         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23222         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23223         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23224
23225         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23226                 error "migrate failed"
23227
23228         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23229                 error "$tdir stripe count mismatch"
23230
23231         for i in $(seq 0 9); do
23232                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23233                         error "d$i is striped"
23234         done
23235 }
23236 run_test 230w "non-recursive mode dir migration"
23237
23238 test_230x() {
23239         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23240         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23241                 skip "Need MDS version at least 2.15.0"
23242
23243         mkdir -p $DIR/$tdir || error "mkdir failed"
23244         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23245
23246         local mdt_name=$(mdtname_from_index 0)
23247         local low=$(do_facet mds2 $LCTL get_param -n \
23248                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23249         local high=$(do_facet mds2 $LCTL get_param -n \
23250                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23251         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23252         local maxage=$(do_facet mds2 $LCTL get_param -n \
23253                 osp.*$mdt_name-osp-MDT0001.maxage)
23254
23255         stack_trap "do_facet mds2 $LCTL set_param -n \
23256                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23257                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23258         stack_trap "do_facet mds2 $LCTL set_param -n \
23259                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23260
23261         do_facet mds2 $LCTL set_param -n \
23262                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23263         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23264         sleep 4
23265         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23266                 error "migrate $tdir should fail"
23267
23268         do_facet mds2 $LCTL set_param -n \
23269                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23270         do_facet mds2 $LCTL set_param -n \
23271                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23272         sleep 4
23273         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23274                 error "migrate failed"
23275         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23276                 error "$tdir stripe count mismatch"
23277 }
23278 run_test 230x "dir migration check space"
23279
23280 test_230y() {
23281         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23282         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23283                 skip "Need MDS version at least 2.15.55.45"
23284
23285         local pid
23286
23287         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23288         $LFS getdirstripe $DIR/$tdir
23289         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23290         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23291         pid=$!
23292         sleep 1
23293
23294         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23295         do_facet mds2 lctl set_param fail_loc=0x1802
23296
23297         wait $pid
23298         do_facet mds2 lctl set_param fail_loc=0
23299         $LFS getdirstripe $DIR/$tdir
23300         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23301         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23302 }
23303 run_test 230y "unlink dir with bad hash type"
23304
23305 test_230z() {
23306         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23307         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23308                 skip "Need MDS version at least 2.15.55.45"
23309
23310         local pid
23311
23312         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23313         $LFS getdirstripe $DIR/$tdir
23314         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23315         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23316         pid=$!
23317         sleep 1
23318
23319         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23320         do_facet mds2 lctl set_param fail_loc=0x1802
23321
23322         wait $pid
23323         do_facet mds2 lctl set_param fail_loc=0
23324         $LFS getdirstripe $DIR/$tdir
23325
23326         # resume migration
23327         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23328                 error "resume migration failed"
23329         $LFS getdirstripe $DIR/$tdir
23330         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23331                 error "migration is not finished"
23332 }
23333 run_test 230z "resume dir migration with bad hash type"
23334
23335 test_231a()
23336 {
23337         # For simplicity this test assumes that max_pages_per_rpc
23338         # is the same across all OSCs
23339         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23340         local bulk_size=$((max_pages * PAGE_SIZE))
23341         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23342                                        head -n 1)
23343
23344         mkdir -p $DIR/$tdir
23345         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23346                 error "failed to set stripe with -S ${brw_size}M option"
23347         stack_trap "rm -rf $DIR/$tdir"
23348
23349         # clear the OSC stats
23350         $LCTL set_param osc.*.stats=0 &>/dev/null
23351         stop_writeback
23352
23353         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23354         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23355                 oflag=direct &>/dev/null || error "dd failed"
23356
23357         sync; sleep 1; sync # just to be safe
23358         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23359         if [ x$nrpcs != "x1" ]; then
23360                 $LCTL get_param osc.*.stats
23361                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23362         fi
23363
23364         start_writeback
23365         # Drop the OSC cache, otherwise we will read from it
23366         cancel_lru_locks osc
23367
23368         # clear the OSC stats
23369         $LCTL set_param osc.*.stats=0 &>/dev/null
23370
23371         # Client reads $bulk_size.
23372         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23373                 iflag=direct &>/dev/null || error "dd failed"
23374
23375         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23376         if [ x$nrpcs != "x1" ]; then
23377                 $LCTL get_param osc.*.stats
23378                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23379         fi
23380 }
23381 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23382
23383 test_231b() {
23384         mkdir -p $DIR/$tdir
23385         stack_trap "rm -rf $DIR/$tdir"
23386         local i
23387         for i in {0..1023}; do
23388                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23389                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23390                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23391         done
23392         sync
23393 }
23394 run_test 231b "must not assert on fully utilized OST request buffer"
23395
23396 test_232a() {
23397         mkdir -p $DIR/$tdir
23398         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23399
23400         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23401         do_facet ost1 $LCTL set_param fail_loc=0x31c
23402
23403         # ignore dd failure
23404         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23405         stack_trap "rm -f $DIR/$tdir/$tfile"
23406
23407         do_facet ost1 $LCTL set_param fail_loc=0
23408         umount_client $MOUNT || error "umount failed"
23409         mount_client $MOUNT || error "mount failed"
23410         stop ost1 || error "cannot stop ost1"
23411         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23412 }
23413 run_test 232a "failed lock should not block umount"
23414
23415 test_232b() {
23416         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23417                 skip "Need MDS version at least 2.10.58"
23418
23419         mkdir -p $DIR/$tdir
23420         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23421         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23422         stack_trap "rm -f $DIR/$tdir/$tfile"
23423         sync
23424         cancel_lru_locks osc
23425
23426         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23427         do_facet ost1 $LCTL set_param fail_loc=0x31c
23428
23429         # ignore failure
23430         $LFS data_version $DIR/$tdir/$tfile || true
23431
23432         do_facet ost1 $LCTL set_param fail_loc=0
23433         umount_client $MOUNT || error "umount failed"
23434         mount_client $MOUNT || error "mount failed"
23435         stop ost1 || error "cannot stop ost1"
23436         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23437 }
23438 run_test 232b "failed data version lock should not block umount"
23439
23440 test_233a() {
23441         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23442                 skip "Need MDS version at least 2.3.64"
23443         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23444
23445         local fid=$($LFS path2fid $MOUNT)
23446
23447         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23448                 error "cannot access $MOUNT using its FID '$fid'"
23449 }
23450 run_test 233a "checking that OBF of the FS root succeeds"
23451
23452 test_233b() {
23453         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23454                 skip "Need MDS version at least 2.5.90"
23455         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23456
23457         local fid=$($LFS path2fid $MOUNT/.lustre)
23458
23459         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23460                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23461
23462         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23463         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23464                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23465 }
23466 run_test 233b "checking that OBF of the FS .lustre succeeds"
23467
23468 test_234() {
23469         local p="$TMP/sanityN-$TESTNAME.parameters"
23470         save_lustre_params client "llite.*.xattr_cache" > $p
23471         lctl set_param llite.*.xattr_cache 1 ||
23472                 skip_env "xattr cache is not supported"
23473
23474         mkdir -p $DIR/$tdir || error "mkdir failed"
23475         touch $DIR/$tdir/$tfile || error "touch failed"
23476         # OBD_FAIL_LLITE_XATTR_ENOMEM
23477         $LCTL set_param fail_loc=0x1405
23478         getfattr -n user.attr $DIR/$tdir/$tfile &&
23479                 error "getfattr should have failed with ENOMEM"
23480         $LCTL set_param fail_loc=0x0
23481         rm -rf $DIR/$tdir
23482
23483         restore_lustre_params < $p
23484         rm -f $p
23485 }
23486 run_test 234 "xattr cache should not crash on ENOMEM"
23487
23488 test_235() {
23489         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23490                 skip "Need MDS version at least 2.4.52"
23491
23492         flock_deadlock $DIR/$tfile
23493         local RC=$?
23494         case $RC in
23495                 0)
23496                 ;;
23497                 124) error "process hangs on a deadlock"
23498                 ;;
23499                 *) error "error executing flock_deadlock $DIR/$tfile"
23500                 ;;
23501         esac
23502 }
23503 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23504
23505 #LU-2935
23506 test_236() {
23507         check_swap_layouts_support
23508
23509         local ref1=/etc/passwd
23510         local ref2=/etc/group
23511         local file1=$DIR/$tdir/f1
23512         local file2=$DIR/$tdir/f2
23513
23514         test_mkdir -c1 $DIR/$tdir
23515         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23516         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23517         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23518         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23519         local fd=$(free_fd)
23520         local cmd="exec $fd<>$file2"
23521         eval $cmd
23522         rm $file2
23523         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23524                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23525         cmd="exec $fd>&-"
23526         eval $cmd
23527         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23528
23529         #cleanup
23530         rm -rf $DIR/$tdir
23531 }
23532 run_test 236 "Layout swap on open unlinked file"
23533
23534 # LU-4659 linkea consistency
23535 test_238() {
23536         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23537                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23538                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23539                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23540
23541         touch $DIR/$tfile
23542         ln $DIR/$tfile $DIR/$tfile.lnk
23543         touch $DIR/$tfile.new
23544         mv $DIR/$tfile.new $DIR/$tfile
23545         local fid1=$($LFS path2fid $DIR/$tfile)
23546         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23547         local path1=$($LFS fid2path $FSNAME "$fid1")
23548         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23549         local path2=$($LFS fid2path $FSNAME "$fid2")
23550         [ $tfile.lnk == $path2 ] ||
23551                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23552         rm -f $DIR/$tfile*
23553 }
23554 run_test 238 "Verify linkea consistency"
23555
23556 test_239A() { # was test_239
23557         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23558                 skip "Need MDS version at least 2.5.60"
23559
23560         local list=$(comma_list $(mdts_nodes))
23561
23562         mkdir -p $DIR/$tdir
23563         createmany -o $DIR/$tdir/f- 5000
23564         unlinkmany $DIR/$tdir/f- 5000
23565         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23566                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23567         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23568                         osp.*MDT*.sync_in_flight" | calc_sum)
23569         [ "$changes" -eq 0 ] || error "$changes not synced"
23570 }
23571 run_test 239A "osp_sync test"
23572
23573 test_239a() { #LU-5297
23574         remote_mds_nodsh && skip "remote MDS with nodsh"
23575
23576         touch $DIR/$tfile
23577         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23578         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23579         chgrp $RUNAS_GID $DIR/$tfile
23580         wait_delete_completed
23581 }
23582 run_test 239a "process invalid osp sync record correctly"
23583
23584 test_239b() { #LU-5297
23585         remote_mds_nodsh && skip "remote MDS with nodsh"
23586
23587         touch $DIR/$tfile1
23588         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23589         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23590         chgrp $RUNAS_GID $DIR/$tfile1
23591         wait_delete_completed
23592         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23593         touch $DIR/$tfile2
23594         chgrp $RUNAS_GID $DIR/$tfile2
23595         wait_delete_completed
23596 }
23597 run_test 239b "process osp sync record with ENOMEM error correctly"
23598
23599 test_240() {
23600         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23601         remote_mds_nodsh && skip "remote MDS with nodsh"
23602
23603         mkdir -p $DIR/$tdir
23604
23605         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23606                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23607         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23608                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23609
23610         umount_client $MOUNT || error "umount failed"
23611         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23612         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23613         mount_client $MOUNT || error "failed to mount client"
23614
23615         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23616         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23617 }
23618 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23619
23620 test_241_bio() {
23621         local count=$1
23622         local bsize=$2
23623
23624         for LOOP in $(seq $count); do
23625                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23626                 cancel_lru_locks $OSC || true
23627         done
23628 }
23629
23630 test_241_dio() {
23631         local count=$1
23632         local bsize=$2
23633
23634         for LOOP in $(seq $1); do
23635                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23636                         2>/dev/null
23637         done
23638 }
23639
23640 test_241a() { # was test_241
23641         local bsize=$PAGE_SIZE
23642
23643         (( bsize < 40960 )) && bsize=40960
23644         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23645         ls -la $DIR/$tfile
23646         cancel_lru_locks $OSC
23647         test_241_bio 1000 $bsize &
23648         PID=$!
23649         test_241_dio 1000 $bsize
23650         wait $PID
23651 }
23652 run_test 241a "bio vs dio"
23653
23654 test_241b() {
23655         local bsize=$PAGE_SIZE
23656
23657         (( bsize < 40960 )) && bsize=40960
23658         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23659         ls -la $DIR/$tfile
23660         test_241_dio 1000 $bsize &
23661         PID=$!
23662         test_241_dio 1000 $bsize
23663         wait $PID
23664 }
23665 run_test 241b "dio vs dio"
23666
23667 test_242() {
23668         remote_mds_nodsh && skip "remote MDS with nodsh"
23669
23670         mkdir_on_mdt0 $DIR/$tdir
23671         touch $DIR/$tdir/$tfile
23672
23673         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23674         do_facet mds1 lctl set_param fail_loc=0x105
23675         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23676
23677         do_facet mds1 lctl set_param fail_loc=0
23678         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23679 }
23680 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23681
23682 test_243()
23683 {
23684         test_mkdir $DIR/$tdir
23685         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23686 }
23687 run_test 243 "various group lock tests"
23688
23689 test_244a()
23690 {
23691         test_mkdir $DIR/$tdir
23692         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23693         sendfile_grouplock $DIR/$tdir/$tfile || \
23694                 error "sendfile+grouplock failed"
23695         rm -rf $DIR/$tdir
23696 }
23697 run_test 244a "sendfile with group lock tests"
23698
23699 test_244b()
23700 {
23701         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23702
23703         local threads=50
23704         local size=$((1024*1024))
23705
23706         test_mkdir $DIR/$tdir
23707         for i in $(seq 1 $threads); do
23708                 local file=$DIR/$tdir/file_$((i / 10))
23709                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23710                 local pids[$i]=$!
23711         done
23712         for i in $(seq 1 $threads); do
23713                 wait ${pids[$i]}
23714         done
23715 }
23716 run_test 244b "multi-threaded write with group lock"
23717
23718 test_245a() {
23719         local flagname="multi_mod_rpcs"
23720         local connect_data_name="max_mod_rpcs"
23721         local out
23722
23723         # check if multiple modify RPCs flag is set
23724         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23725                 grep "connect_flags:")
23726         echo "$out"
23727
23728         echo "$out" | grep -qw $flagname
23729         if [ $? -ne 0 ]; then
23730                 echo "connect flag $flagname is not set"
23731                 return
23732         fi
23733
23734         # check if multiple modify RPCs data is set
23735         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23736         echo "$out"
23737
23738         echo "$out" | grep -qw $connect_data_name ||
23739                 error "import should have connect data $connect_data_name"
23740 }
23741 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23742
23743 test_245b() {
23744         local flagname="multi_mod_rpcs"
23745         local connect_data_name="max_mod_rpcs"
23746         local out
23747
23748         remote_mds_nodsh && skip "remote MDS with nodsh"
23749         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23750
23751         # check if multiple modify RPCs flag is set
23752         out=$(do_facet mds1 \
23753               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23754               grep "connect_flags:")
23755         echo "$out"
23756
23757         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23758
23759         # check if multiple modify RPCs data is set
23760         out=$(do_facet mds1 \
23761               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23762
23763         [[ "$out" =~ $connect_data_name ]] ||
23764                 {
23765                         echo "$out"
23766                         error "missing connect data $connect_data_name"
23767                 }
23768 }
23769 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23770
23771 cleanup_247() {
23772         local submount=$1
23773
23774         trap 0
23775         umount_client $submount
23776         rmdir $submount
23777 }
23778
23779 test_247a() {
23780         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23781                 grep -q subtree ||
23782                 skip_env "Fileset feature is not supported"
23783
23784         local submount=${MOUNT}_$tdir
23785
23786         mkdir $MOUNT/$tdir
23787         mkdir -p $submount || error "mkdir $submount failed"
23788         FILESET="$FILESET/$tdir" mount_client $submount ||
23789                 error "mount $submount failed"
23790         trap "cleanup_247 $submount" EXIT
23791         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23792         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23793                 error "read $MOUNT/$tdir/$tfile failed"
23794         cleanup_247 $submount
23795 }
23796 run_test 247a "mount subdir as fileset"
23797
23798 test_247b() {
23799         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23800                 skip_env "Fileset feature is not supported"
23801
23802         local submount=${MOUNT}_$tdir
23803
23804         rm -rf $MOUNT/$tdir
23805         mkdir -p $submount || error "mkdir $submount failed"
23806         SKIP_FILESET=1
23807         FILESET="$FILESET/$tdir" mount_client $submount &&
23808                 error "mount $submount should fail"
23809         rmdir $submount
23810 }
23811 run_test 247b "mount subdir that dose not exist"
23812
23813 test_247c() {
23814         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23815                 skip_env "Fileset feature is not supported"
23816
23817         local submount=${MOUNT}_$tdir
23818
23819         mkdir -p $MOUNT/$tdir/dir1
23820         mkdir -p $submount || error "mkdir $submount failed"
23821         trap "cleanup_247 $submount" EXIT
23822         FILESET="$FILESET/$tdir" mount_client $submount ||
23823                 error "mount $submount failed"
23824         local fid=$($LFS path2fid $MOUNT/)
23825         $LFS fid2path $submount $fid && error "fid2path should fail"
23826         cleanup_247 $submount
23827 }
23828 run_test 247c "running fid2path outside subdirectory root"
23829
23830 test_247d() {
23831         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23832                 skip "Fileset feature is not supported"
23833
23834         local submount=${MOUNT}_$tdir
23835
23836         mkdir -p $MOUNT/$tdir/dir1
23837         mkdir -p $submount || error "mkdir $submount failed"
23838         FILESET="$FILESET/$tdir" mount_client $submount ||
23839                 error "mount $submount failed"
23840         trap "cleanup_247 $submount" EXIT
23841
23842         local td=$submount/dir1
23843         local fid=$($LFS path2fid $td)
23844         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23845
23846         # check that we get the same pathname back
23847         local rootpath
23848         local found
23849         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23850                 echo "$rootpath $fid"
23851                 found=$($LFS fid2path $rootpath "$fid")
23852                 [ -n "$found" ] || error "fid2path should succeed"
23853                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23854         done
23855         # check wrong root path format
23856         rootpath=$submount"_wrong"
23857         found=$($LFS fid2path $rootpath "$fid")
23858         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23859
23860         cleanup_247 $submount
23861 }
23862 run_test 247d "running fid2path inside subdirectory root"
23863
23864 # LU-8037
23865 test_247e() {
23866         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23867                 grep -q subtree ||
23868                 skip "Fileset feature is not supported"
23869
23870         local submount=${MOUNT}_$tdir
23871
23872         mkdir $MOUNT/$tdir
23873         mkdir -p $submount || error "mkdir $submount failed"
23874         FILESET="$FILESET/.." mount_client $submount &&
23875                 error "mount $submount should fail"
23876         rmdir $submount
23877 }
23878 run_test 247e "mount .. as fileset"
23879
23880 test_247f() {
23881         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23882         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23883                 skip "Need at least version 2.14.50.162"
23884         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23885                 skip "Fileset feature is not supported"
23886
23887         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23888         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23889                 error "mkdir remote failed"
23890         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23891                 error "mkdir remote/subdir failed"
23892         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23893                 error "mkdir striped failed"
23894         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23895
23896         local submount=${MOUNT}_$tdir
23897
23898         mkdir -p $submount || error "mkdir $submount failed"
23899         stack_trap "rmdir $submount"
23900
23901         local dir
23902         local fileset=$FILESET
23903         local mdts=$(comma_list $(mdts_nodes))
23904
23905         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23906         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23907                 $tdir/striped/subdir $tdir/striped/.; do
23908                 FILESET="$fileset/$dir" mount_client $submount ||
23909                         error "mount $dir failed"
23910                 umount_client $submount
23911         done
23912 }
23913 run_test 247f "mount striped or remote directory as fileset"
23914
23915 test_subdir_mount_lock()
23916 {
23917         local testdir=$1
23918         local submount=${MOUNT}_$(basename $testdir)
23919
23920         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23921
23922         mkdir -p $submount || error "mkdir $submount failed"
23923         stack_trap "rmdir $submount"
23924
23925         FILESET="$fileset/$testdir" mount_client $submount ||
23926                 error "mount $FILESET failed"
23927         stack_trap "umount $submount"
23928
23929         local mdts=$(comma_list $(mdts_nodes))
23930
23931         local nrpcs
23932
23933         stat $submount > /dev/null || error "stat $submount failed"
23934         cancel_lru_locks $MDC
23935         stat $submount > /dev/null || error "stat $submount failed"
23936         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23937         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23938         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23939         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23940                 awk '/getattr/ {sum += $2} END {print sum}')
23941
23942         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23943 }
23944
23945 test_247g() {
23946         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23947
23948         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23949                 error "mkdir $tdir failed"
23950         test_subdir_mount_lock $tdir
23951 }
23952 run_test 247g "striped directory submount revalidate ROOT from cache"
23953
23954 test_247h() {
23955         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23956         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23957                 skip "Need MDS version at least 2.15.51"
23958
23959         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23960         test_subdir_mount_lock $tdir
23961         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23962         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23963                 error "mkdir $tdir.1 failed"
23964         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23965 }
23966 run_test 247h "remote directory submount revalidate ROOT from cache"
23967
23968 test_248a() {
23969         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23970         [ -z "$fast_read_sav" ] && skip "no fast read support"
23971
23972         # create a large file for fast read verification
23973         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23974
23975         # make sure the file is created correctly
23976         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23977                 { rm -f $DIR/$tfile; skip "file creation error"; }
23978
23979         echo "Test 1: verify that fast read is 4 times faster on cache read"
23980
23981         # small read with fast read enabled
23982         $LCTL set_param -n llite.*.fast_read=1
23983         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23984                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23985                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23986         # small read with fast read disabled
23987         $LCTL set_param -n llite.*.fast_read=0
23988         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23989                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23990                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23991
23992         # verify that fast read is 4 times faster for cache read
23993         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23994                 error_not_in_vm "fast read was not 4 times faster: " \
23995                            "$t_fast vs $t_slow"
23996
23997         echo "Test 2: verify the performance between big and small read"
23998         $LCTL set_param -n llite.*.fast_read=1
23999
24000         # 1k non-cache read
24001         cancel_lru_locks osc
24002         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
24003                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
24004                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
24005
24006         # 1M non-cache read
24007         cancel_lru_locks osc
24008         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
24009                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
24010                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
24011
24012         # verify that big IO is not 4 times faster than small IO
24013         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
24014                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
24015
24016         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
24017         rm -f $DIR/$tfile
24018 }
24019 run_test 248a "fast read verification"
24020
24021 test_248b() {
24022         # Default short_io_bytes=16384, try both smaller and larger sizes.
24023         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
24024         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
24025         echo "bs=53248 count=113 normal buffered write"
24026         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
24027                 error "dd of initial data file failed"
24028         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
24029
24030         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
24031         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
24032                 error "dd with sync normal writes failed"
24033         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
24034
24035         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
24036         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
24037                 error "dd with sync small writes failed"
24038         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
24039
24040         cancel_lru_locks osc
24041
24042         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
24043         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
24044         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
24045         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
24046                 iflag=direct || error "dd with O_DIRECT small read failed"
24047         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
24048         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
24049                 error "compare $TMP/$tfile.1 failed"
24050
24051         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
24052         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
24053
24054         # just to see what the maximum tunable value is, and test parsing
24055         echo "test invalid parameter 2MB"
24056         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
24057                 error "too-large short_io_bytes allowed"
24058         echo "test maximum parameter 512KB"
24059         # if we can set a larger short_io_bytes, run test regardless of version
24060         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
24061                 # older clients may not allow setting it this large, that's OK
24062                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
24063                         skip "Need at least client version 2.13.50"
24064                 error "medium short_io_bytes failed"
24065         fi
24066         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
24067         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
24068
24069         echo "test large parameter 64KB"
24070         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
24071         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
24072
24073         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
24074         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
24075                 error "dd with sync large writes failed"
24076         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
24077
24078         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
24079         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
24080         num=$((113 * 4096 / PAGE_SIZE))
24081         echo "bs=$size count=$num oflag=direct large write $tfile.3"
24082         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
24083                 error "dd with O_DIRECT large writes failed"
24084         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
24085                 error "compare $DIR/$tfile.3 failed"
24086
24087         cancel_lru_locks osc
24088
24089         echo "bs=$size count=$num iflag=direct large read $tfile.2"
24090         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
24091                 error "dd with O_DIRECT large read failed"
24092         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
24093                 error "compare $TMP/$tfile.2 failed"
24094
24095         echo "bs=$size count=$num iflag=direct large read $tfile.3"
24096         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
24097                 error "dd with O_DIRECT large read failed"
24098         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
24099                 error "compare $TMP/$tfile.3 failed"
24100 }
24101 run_test 248b "test short_io read and write for both small and large sizes"
24102
24103 test_248c() {
24104         $LCTL set_param llite.*.read_ahead_stats=c
24105         # This test compares whole file readahead to non-whole file readahead
24106         # The performance should be consistently slightly faster for whole file,
24107         # and the bug caused whole file readahead to be 80-100x slower, but to
24108         # account for possible test system lag, we require whole file to be
24109         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
24110         # test
24111         local time1
24112         local time2
24113         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
24114         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
24115         counter=0
24116
24117         while [ $counter -lt 3 ]; do
24118                 # Increment the counter
24119                 ((counter++))
24120
24121                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
24122                 rm -f $DIR/$tfile
24123                 touch $DIR/$tfile || error "(0) failed to create file"
24124                 # 64 MiB
24125                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
24126                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
24127                 echo "whole file readahead of 64 MiB took $time1 seconds"
24128                 $LCTL get_param llite.*.read_ahead_stats
24129
24130                 $LCTL set_param llite.*.read_ahead_stats=c
24131                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
24132                 rm -f $DIR/$tfile
24133                 touch $DIR/$tfile || error "(2) failed to create file"
24134                 # 64 MiB
24135                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
24136                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
24137                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
24138                 $LCTL get_param llite.*.read_ahead_stats
24139
24140                 # Check if time1 is not more than 1.5 times2
24141                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
24142
24143                 if [[ $timecheck -eq 1 ]]; then
24144                         echo "Test passed on attempt $counter"
24145                         # Exit the loop
24146                         counter=4
24147                 else
24148                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
24149                 fi
24150         done
24151         if [ $counter -eq 3 ]; then
24152                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
24153         fi
24154
24155 }
24156 run_test 248c "verify whole file read behavior"
24157
24158 test_249() { # LU-7890
24159         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
24160                 skip "Need at least version 2.8.54"
24161
24162         rm -f $DIR/$tfile
24163         $LFS setstripe -c 1 $DIR/$tfile
24164         # Offset 2T == 4k * 512M
24165         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
24166                 error "dd to 2T offset failed"
24167 }
24168 run_test 249 "Write above 2T file size"
24169
24170 test_250() {
24171         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
24172          && skip "no 16TB file size limit on ZFS"
24173
24174         $LFS setstripe -c 1 $DIR/$tfile
24175         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
24176         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
24177         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
24178         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
24179                 conv=notrunc,fsync && error "append succeeded"
24180         return 0
24181 }
24182 run_test 250 "Write above 16T limit"
24183
24184 test_251a() {
24185         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
24186
24187         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
24188         #Skip once - writing the first stripe will succeed
24189         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24190         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
24191                 error "short write happened"
24192
24193         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24194         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
24195                 error "short read happened"
24196
24197         rm -f $DIR/$tfile
24198 }
24199 run_test 251a "Handling short read and write correctly"
24200
24201 test_251b() {
24202         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24203                 error "write $tfile failed"
24204
24205         sleep 2 && echo 12345 >> $DIR/$tfile &
24206
24207         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24208         $LCTL set_param fail_loc=0x1431 fail_val=5
24209         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24210         # 5 seconds, read 10 bytes, the short read should
24211         # report:
24212         #                start ->+ read_len -> offset_after_read read_count
24213         #     short read: 4096 ->+ 10 -> 4096 0
24214         # not:
24215         #     short read: 4096 ->+ 10 -> 4102 0
24216         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24217                         awk '/short read/ { print $7 }')
24218         (( off == 4096 )) ||
24219                 error "short read should set offset at 4096, not $off"
24220 }
24221 run_test 251b "short read restore offset correctly"
24222
24223 test_252() {
24224         remote_mds_nodsh && skip "remote MDS with nodsh"
24225         remote_ost_nodsh && skip "remote OST with nodsh"
24226         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24227                 skip_env "ldiskfs only test"
24228         fi
24229
24230         local tgt
24231         local dev
24232         local out
24233         local uuid
24234         local num
24235         local gen
24236
24237         # check lr_reader on OST0000
24238         tgt=ost1
24239         dev=$(facet_device $tgt)
24240         out=$(do_facet $tgt $LR_READER $dev)
24241         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24242         echo "$out"
24243         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24244         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24245                 error "Invalid uuid returned by $LR_READER on target $tgt"
24246         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24247
24248         # check lr_reader -c on MDT0000
24249         tgt=mds1
24250         dev=$(facet_device $tgt)
24251         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24252                 skip "$LR_READER does not support additional options"
24253         fi
24254         out=$(do_facet $tgt $LR_READER -c $dev)
24255         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24256         echo "$out"
24257         num=$(echo "$out" | grep -c "mdtlov")
24258         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24259                 error "Invalid number of mdtlov clients returned by $LR_READER"
24260         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24261
24262         # check lr_reader -cr on MDT0000
24263         out=$(do_facet $tgt $LR_READER -cr $dev)
24264         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24265         echo "$out"
24266         echo "$out" | grep -q "^reply_data:$" ||
24267                 error "$LR_READER should have returned 'reply_data' section"
24268         num=$(echo "$out" | grep -c "client_generation")
24269         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24270 }
24271 run_test 252 "check lr_reader tool"
24272
24273 test_253() {
24274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24275         remote_mds_nodsh && skip "remote MDS with nodsh"
24276         remote_mgs_nodsh && skip "remote MGS with nodsh"
24277         check_set_fallocate_or_skip
24278
24279         local ostidx=0
24280         local rc=0
24281         local ost_name=$(ostname_from_index $ostidx)
24282
24283         # on the mdt's osc
24284         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24285         do_facet $SINGLEMDS $LCTL get_param -n \
24286                 osp.$mdtosc_proc1.reserved_mb_high ||
24287                 skip  "remote MDS does not support reserved_mb_high"
24288
24289         rm -rf $DIR/$tdir
24290         wait_mds_ost_sync
24291         wait_delete_completed
24292         mkdir $DIR/$tdir
24293         stack_trap "rm -rf $DIR/$tdir"
24294
24295         pool_add $TESTNAME || error "Pool creation failed"
24296         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24297
24298         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24299                 error "Setstripe failed"
24300
24301         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24302
24303         local wms=$(ost_watermarks_get $ostidx)
24304
24305         ost_watermarks_set $ostidx 60 50
24306         stack_trap "ost_watermarks_set $ostidx $wms"
24307
24308         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24309         local size=$((free_kb * 1024))
24310
24311         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24312                 error "fallocate failed"
24313         sleep_maxage
24314
24315         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24316                         osp.$mdtosc_proc1.prealloc_status)
24317         echo "prealloc_status $oa_status"
24318
24319         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24320                 error "File creation should fail"
24321
24322         #object allocation was stopped, but we still able to append files
24323         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24324                 oflag=append || error "Append failed"
24325
24326         rm -f $DIR/$tdir/$tfile.0
24327         rm -f $DIR/$tdir/fill_ost$ostidx
24328
24329         wait_delete_completed
24330         sleep_maxage
24331
24332         for i in $(seq 10 12); do
24333                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24334                         2>/dev/null || error "File creation failed after rm"
24335         done
24336
24337         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24338                         osp.$mdtosc_proc1.prealloc_status)
24339         echo "prealloc_status $oa_status"
24340
24341         if (( oa_status != 0 )); then
24342                 error "Object allocation still disable after rm"
24343         fi
24344 }
24345 run_test 253 "Check object allocation limit"
24346
24347 test_254() {
24348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24349         remote_mds_nodsh && skip "remote MDS with nodsh"
24350
24351         local mdt=$(facet_svc $SINGLEMDS)
24352
24353         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24354                 skip "MDS does not support changelog_size"
24355
24356         local cl_user
24357
24358         changelog_register || error "changelog_register failed"
24359
24360         changelog_clear 0 || error "changelog_clear failed"
24361
24362         local size1=$(do_facet $SINGLEMDS \
24363                       $LCTL get_param -n mdd.$mdt.changelog_size)
24364         echo "Changelog size $size1"
24365
24366         rm -rf $DIR/$tdir
24367         $LFS mkdir -i 0 $DIR/$tdir
24368         # change something
24369         mkdir -p $DIR/$tdir/pics/2008/zachy
24370         touch $DIR/$tdir/pics/2008/zachy/timestamp
24371         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24372         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24373         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24374         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24375         rm $DIR/$tdir/pics/desktop.jpg
24376
24377         local size2=$(do_facet $SINGLEMDS \
24378                       $LCTL get_param -n mdd.$mdt.changelog_size)
24379         echo "Changelog size after work $size2"
24380
24381         (( $size2 > $size1 )) ||
24382                 error "new Changelog size=$size2 less than old size=$size1"
24383 }
24384 run_test 254 "Check changelog size"
24385
24386 ladvise_no_type()
24387 {
24388         local type=$1
24389         local file=$2
24390
24391         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24392                 awk -F: '{print $2}' | grep $type > /dev/null
24393         if [ $? -ne 0 ]; then
24394                 return 0
24395         fi
24396         return 1
24397 }
24398
24399 ladvise_no_ioctl()
24400 {
24401         local file=$1
24402
24403         lfs ladvise -a willread $file > /dev/null 2>&1
24404         if [ $? -eq 0 ]; then
24405                 return 1
24406         fi
24407
24408         lfs ladvise -a willread $file 2>&1 |
24409                 grep "Inappropriate ioctl for device" > /dev/null
24410         if [ $? -eq 0 ]; then
24411                 return 0
24412         fi
24413         return 1
24414 }
24415
24416 percent() {
24417         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24418 }
24419
24420 # run a random read IO workload
24421 # usage: random_read_iops <filename> <filesize> <iosize>
24422 random_read_iops() {
24423         local file=$1
24424         local fsize=$2
24425         local iosize=${3:-4096}
24426
24427         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24428                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24429 }
24430
24431 drop_file_oss_cache() {
24432         local file="$1"
24433         local nodes="$2"
24434
24435         $LFS ladvise -a dontneed $file 2>/dev/null ||
24436                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24437 }
24438
24439 ladvise_willread_performance()
24440 {
24441         local repeat=10
24442         local average_origin=0
24443         local average_cache=0
24444         local average_ladvise=0
24445
24446         for ((i = 1; i <= $repeat; i++)); do
24447                 echo "Iter $i/$repeat: reading without willread hint"
24448                 cancel_lru_locks osc
24449                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24450                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24451                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24452                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24453
24454                 cancel_lru_locks osc
24455                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24456                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24457                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24458
24459                 cancel_lru_locks osc
24460                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24461                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24462                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24463                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24464                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24465         done
24466         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24467         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24468         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24469
24470         speedup_cache=$(percent $average_cache $average_origin)
24471         speedup_ladvise=$(percent $average_ladvise $average_origin)
24472
24473         echo "Average uncached read: $average_origin"
24474         echo "Average speedup with OSS cached read:" \
24475                 "$average_cache = +$speedup_cache%"
24476         echo "Average speedup with ladvise willread:" \
24477                 "$average_ladvise = +$speedup_ladvise%"
24478
24479         local lowest_speedup=20
24480         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24481                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24482                      "got $speedup_cache%. Skipping ladvise willread check."
24483                 return 0
24484         fi
24485
24486         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24487         # it is still good to run until then to exercise 'ladvise willread'
24488         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24489                 [ "$ost1_FSTYPE" = "zfs" ] &&
24490                 echo "osd-zfs does not support dontneed or drop_caches" &&
24491                 return 0
24492
24493         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24494         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24495                 error_not_in_vm "Speedup with willread is less than " \
24496                         "$lowest_speedup%, got $speedup_ladvise%"
24497 }
24498
24499 test_255a() {
24500         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24501                 skip "lustre < 2.8.54 does not support ladvise "
24502         remote_ost_nodsh && skip "remote OST with nodsh"
24503
24504         stack_trap "rm -f $DIR/$tfile"
24505         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24506
24507         ladvise_no_type willread $DIR/$tfile &&
24508                 skip "willread ladvise is not supported"
24509
24510         ladvise_no_ioctl $DIR/$tfile &&
24511                 skip "ladvise ioctl is not supported"
24512
24513         local size_mb=100
24514         local size=$((size_mb * 1048576))
24515         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24516                 error "dd to $DIR/$tfile failed"
24517
24518         lfs ladvise -a willread $DIR/$tfile ||
24519                 error "Ladvise failed with no range argument"
24520
24521         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24522                 error "Ladvise failed with no -l or -e argument"
24523
24524         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24525                 error "Ladvise failed with only -e argument"
24526
24527         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24528                 error "Ladvise failed with only -l argument"
24529
24530         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24531                 error "End offset should not be smaller than start offset"
24532
24533         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24534                 error "End offset should not be equal to start offset"
24535
24536         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24537                 error "Ladvise failed with overflowing -s argument"
24538
24539         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24540                 error "Ladvise failed with overflowing -e argument"
24541
24542         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24543                 error "Ladvise failed with overflowing -l argument"
24544
24545         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24546                 error "Ladvise succeeded with conflicting -l and -e arguments"
24547
24548         echo "Synchronous ladvise should wait"
24549         local delay=8
24550 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24551         do_nodes $(comma_list $(osts_nodes)) \
24552                 $LCTL set_param fail_val=$delay fail_loc=0x237
24553         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24554                 $LCTL set_param fail_loc=0"
24555
24556         local start_ts=$SECONDS
24557         lfs ladvise -a willread $DIR/$tfile ||
24558                 error "Ladvise failed with no range argument"
24559         local end_ts=$SECONDS
24560         local inteval_ts=$((end_ts - start_ts))
24561
24562         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24563                 error "Synchronous advice didn't wait reply"
24564         fi
24565
24566         echo "Asynchronous ladvise shouldn't wait"
24567         local start_ts=$SECONDS
24568         lfs ladvise -a willread -b $DIR/$tfile ||
24569                 error "Ladvise failed with no range argument"
24570         local end_ts=$SECONDS
24571         local inteval_ts=$((end_ts - start_ts))
24572
24573         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24574                 error "Asynchronous advice blocked"
24575         fi
24576
24577         ladvise_willread_performance
24578 }
24579 run_test 255a "check 'lfs ladvise -a willread'"
24580
24581 facet_meminfo() {
24582         local facet=$1
24583         local info=$2
24584
24585         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24586 }
24587
24588 test_255b() {
24589         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24590                 skip "lustre < 2.8.54 does not support ladvise "
24591         remote_ost_nodsh && skip "remote OST with nodsh"
24592
24593         stack_trap "rm -f $DIR/$tfile"
24594         lfs setstripe -c 1 -i 0 $DIR/$tfile
24595
24596         ladvise_no_type dontneed $DIR/$tfile &&
24597                 skip "dontneed ladvise is not supported"
24598
24599         ladvise_no_ioctl $DIR/$tfile &&
24600                 skip "ladvise ioctl is not supported"
24601
24602         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24603                 [ "$ost1_FSTYPE" = "zfs" ] &&
24604                 skip "zfs-osd does not support 'ladvise dontneed'"
24605
24606         local size_mb=100
24607         local size=$((size_mb * 1048576))
24608         # In order to prevent disturbance of other processes, only check 3/4
24609         # of the memory usage
24610         local kibibytes=$((size_mb * 1024 * 3 / 4))
24611
24612         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24613                 error "dd to $DIR/$tfile failed"
24614
24615         #force write to complete before dropping OST cache & checking memory
24616         sync
24617
24618         local total=$(facet_meminfo ost1 MemTotal)
24619         echo "Total memory: $total KiB"
24620
24621         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24622         local before_read=$(facet_meminfo ost1 Cached)
24623         echo "Cache used before read: $before_read KiB"
24624
24625         lfs ladvise -a willread $DIR/$tfile ||
24626                 error "Ladvise willread failed"
24627         local after_read=$(facet_meminfo ost1 Cached)
24628         echo "Cache used after read: $after_read KiB"
24629
24630         lfs ladvise -a dontneed $DIR/$tfile ||
24631                 error "Ladvise dontneed again failed"
24632         local no_read=$(facet_meminfo ost1 Cached)
24633         echo "Cache used after dontneed ladvise: $no_read KiB"
24634
24635         if [ $total -lt $((before_read + kibibytes)) ]; then
24636                 echo "Memory is too small, abort checking"
24637                 return 0
24638         fi
24639
24640         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24641                 error "Ladvise willread should use more memory" \
24642                         "than $kibibytes KiB"
24643         fi
24644
24645         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24646                 error "Ladvise dontneed should release more memory" \
24647                         "than $kibibytes KiB"
24648         fi
24649 }
24650 run_test 255b "check 'lfs ladvise -a dontneed'"
24651
24652 test_255c() {
24653         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24654                 skip "lustre < 2.10.50 does not support lockahead"
24655
24656         local ost1_imp=$(get_osc_import_name client ost1)
24657         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24658                          cut -d'.' -f2)
24659         local count
24660         local new_count
24661         local difference
24662         local i
24663         local rc
24664
24665         test_mkdir -p $DIR/$tdir
24666         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24667
24668         #test 10 returns only success/failure
24669         i=10
24670         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24671         rc=$?
24672         if [ $rc -eq 255 ]; then
24673                 error "Ladvise test${i} failed, ${rc}"
24674         fi
24675
24676         #test 11 counts lock enqueue requests, all others count new locks
24677         i=11
24678         count=$(do_facet ost1 \
24679                 $LCTL get_param -n ost.OSS.ost.stats)
24680         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24681
24682         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24683         rc=$?
24684         if [ $rc -eq 255 ]; then
24685                 error "Ladvise test${i} failed, ${rc}"
24686         fi
24687
24688         new_count=$(do_facet ost1 \
24689                 $LCTL get_param -n ost.OSS.ost.stats)
24690         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24691                    awk '{ print $2 }')
24692
24693         difference="$((new_count - count))"
24694         if [ $difference -ne $rc ]; then
24695                 error "Ladvise test${i}, bad enqueue count, returned " \
24696                       "${rc}, actual ${difference}"
24697         fi
24698
24699         for i in $(seq 12 21); do
24700                 # If we do not do this, we run the risk of having too many
24701                 # locks and starting lock cancellation while we are checking
24702                 # lock counts.
24703                 cancel_lru_locks osc
24704
24705                 count=$($LCTL get_param -n \
24706                        ldlm.namespaces.$imp_name.lock_unused_count)
24707
24708                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24709                 rc=$?
24710                 if [ $rc -eq 255 ]; then
24711                         error "Ladvise test ${i} failed, ${rc}"
24712                 fi
24713
24714                 new_count=$($LCTL get_param -n \
24715                        ldlm.namespaces.$imp_name.lock_unused_count)
24716                 difference="$((new_count - count))"
24717
24718                 # Test 15 output is divided by 100 to map down to valid return
24719                 if [ $i -eq 15 ]; then
24720                         rc="$((rc * 100))"
24721                 fi
24722
24723                 if [ $difference -ne $rc ]; then
24724                         error "Ladvise test ${i}, bad lock count, returned " \
24725                               "${rc}, actual ${difference}"
24726                 fi
24727         done
24728
24729         #test 22 returns only success/failure
24730         i=22
24731         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24732         rc=$?
24733         if [ $rc -eq 255 ]; then
24734                 error "Ladvise test${i} failed, ${rc}"
24735         fi
24736 }
24737 run_test 255c "suite of ladvise lockahead tests"
24738
24739 test_256() {
24740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24741         remote_mds_nodsh && skip "remote MDS with nodsh"
24742         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24743         changelog_users $SINGLEMDS | grep "^cl" &&
24744                 skip "active changelog user"
24745
24746         local cl_user
24747         local cat_sl
24748         local mdt_dev
24749
24750         mdt_dev=$(facet_device $SINGLEMDS)
24751         echo $mdt_dev
24752
24753         changelog_register || error "changelog_register failed"
24754
24755         rm -rf $DIR/$tdir
24756         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24757
24758         changelog_clear 0 || error "changelog_clear failed"
24759
24760         # change something
24761         touch $DIR/$tdir/{1..10}
24762
24763         # stop the MDT
24764         stop $SINGLEMDS || error "Fail to stop MDT"
24765
24766         # remount the MDT
24767         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24768                 error "Fail to start MDT"
24769
24770         #after mount new plainllog is used
24771         touch $DIR/$tdir/{11..19}
24772         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24773         stack_trap "rm -f $tmpfile"
24774         cat_sl=$(do_facet $SINGLEMDS "sync; \
24775                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24776                  llog_reader $tmpfile | grep -c type=1064553b")
24777         do_facet $SINGLEMDS llog_reader $tmpfile
24778
24779         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24780
24781         changelog_clear 0 || error "changelog_clear failed"
24782
24783         cat_sl=$(do_facet $SINGLEMDS "sync; \
24784                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24785                  llog_reader $tmpfile | grep -c type=1064553b")
24786
24787         if (( cat_sl == 2 )); then
24788                 error "Empty plain llog was not deleted from changelog catalog"
24789         elif (( cat_sl != 1 )); then
24790                 error "Active plain llog shouldn't be deleted from catalog"
24791         fi
24792 }
24793 run_test 256 "Check llog delete for empty and not full state"
24794
24795 test_257() {
24796         remote_mds_nodsh && skip "remote MDS with nodsh"
24797         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24798                 skip "Need MDS version at least 2.8.55"
24799
24800         test_mkdir $DIR/$tdir
24801
24802         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24803                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24804         stat $DIR/$tdir
24805
24806 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24807         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24808         local facet=mds$((mdtidx + 1))
24809         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24810         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24811
24812         stop $facet || error "stop MDS failed"
24813         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24814                 error "start MDS fail"
24815         wait_recovery_complete $facet
24816 }
24817 run_test 257 "xattr locks are not lost"
24818
24819 # Verify we take the i_mutex when security requires it
24820 test_258a() {
24821 #define OBD_FAIL_IMUTEX_SEC 0x141c
24822         $LCTL set_param fail_loc=0x141c
24823         touch $DIR/$tfile
24824         chmod u+s $DIR/$tfile
24825         chmod a+rwx $DIR/$tfile
24826         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24827         RC=$?
24828         if [ $RC -ne 0 ]; then
24829                 error "error, failed to take i_mutex, rc=$?"
24830         fi
24831         rm -f $DIR/$tfile
24832 }
24833 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24834
24835 # Verify we do NOT take the i_mutex in the normal case
24836 test_258b() {
24837 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24838         $LCTL set_param fail_loc=0x141d
24839         touch $DIR/$tfile
24840         chmod a+rwx $DIR
24841         chmod a+rw $DIR/$tfile
24842         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24843         RC=$?
24844         if [ $RC -ne 0 ]; then
24845                 error "error, took i_mutex unnecessarily, rc=$?"
24846         fi
24847         rm -f $DIR/$tfile
24848
24849 }
24850 run_test 258b "verify i_mutex security behavior"
24851
24852 test_259() {
24853         local file=$DIR/$tfile
24854         local before
24855         local after
24856
24857         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24858
24859         stack_trap "rm -f $file" EXIT
24860
24861         wait_delete_completed
24862         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24863         echo "before: $before"
24864
24865         $LFS setstripe -i 0 -c 1 $file
24866         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24867         sync_all_data
24868         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24869         echo "after write: $after"
24870
24871 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24872         do_facet ost1 $LCTL set_param fail_loc=0x2301
24873         $TRUNCATE $file 0
24874         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24875         echo "after truncate: $after"
24876
24877         stop ost1
24878         do_facet ost1 $LCTL set_param fail_loc=0
24879         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24880         sleep 2
24881         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24882         echo "after restart: $after"
24883         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24884                 error "missing truncate?"
24885
24886         return 0
24887 }
24888 run_test 259 "crash at delayed truncate"
24889
24890 test_260() {
24891 #define OBD_FAIL_MDC_CLOSE               0x806
24892         $LCTL set_param fail_loc=0x80000806
24893         touch $DIR/$tfile
24894
24895 }
24896 run_test 260 "Check mdc_close fail"
24897
24898 ### Data-on-MDT sanity tests ###
24899 test_270a() {
24900         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24901                 skip "Need MDS version at least 2.10.55 for DoM"
24902
24903         # create DoM file
24904         local dom=$DIR/$tdir/dom_file
24905         local tmp=$DIR/$tdir/tmp_file
24906
24907         mkdir_on_mdt0 $DIR/$tdir
24908
24909         # basic checks for DoM component creation
24910         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24911                 error "Can set MDT layout to non-first entry"
24912
24913         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24914                 error "Can define multiple entries as MDT layout"
24915
24916         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24917
24918         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24919         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24920         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24921
24922         local mdtidx=$($LFS getstripe -m $dom)
24923         local mdtname=MDT$(printf %04x $mdtidx)
24924         local facet=mds$((mdtidx + 1))
24925         local space_check=1
24926
24927         # Skip free space checks with ZFS
24928         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24929
24930         # write
24931         sync
24932         local size_tmp=$((65536 * 3))
24933         local mdtfree1=$(do_facet $facet \
24934                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24935
24936         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24937         # check also direct IO along write
24938         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24939         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24940         sync
24941         cmp $tmp $dom || error "file data is different"
24942         [ $(stat -c%s $dom) == $size_tmp ] ||
24943                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24944         if [ $space_check == 1 ]; then
24945                 local mdtfree2=$(do_facet $facet \
24946                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24947
24948                 # increase in usage from by $size_tmp
24949                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24950                         error "MDT free space wrong after write: " \
24951                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24952         fi
24953
24954         # truncate
24955         local size_dom=10000
24956
24957         $TRUNCATE $dom $size_dom
24958         [ $(stat -c%s $dom) == $size_dom ] ||
24959                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24960         if [ $space_check == 1 ]; then
24961                 mdtfree1=$(do_facet $facet \
24962                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24963                 # decrease in usage from $size_tmp to new $size_dom
24964                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24965                   $(((size_tmp - size_dom) / 1024)) ] ||
24966                         error "MDT free space is wrong after truncate: " \
24967                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24968         fi
24969
24970         # append
24971         cat $tmp >> $dom
24972         sync
24973         size_dom=$((size_dom + size_tmp))
24974         [ $(stat -c%s $dom) == $size_dom ] ||
24975                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24976         if [ $space_check == 1 ]; then
24977                 mdtfree2=$(do_facet $facet \
24978                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24979                 # increase in usage by $size_tmp from previous
24980                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24981                         error "MDT free space is wrong after append: " \
24982                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24983         fi
24984
24985         # delete
24986         rm $dom
24987         if [ $space_check == 1 ]; then
24988                 mdtfree1=$(do_facet $facet \
24989                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24990                 # decrease in usage by $size_dom from previous
24991                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24992                         error "MDT free space is wrong after removal: " \
24993                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24994         fi
24995
24996         # combined striping
24997         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24998                 error "Can't create DoM + OST striping"
24999
25000         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
25001         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
25002         # check also direct IO along write
25003         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
25004         sync
25005         cmp $tmp $dom || error "file data is different"
25006         [ $(stat -c%s $dom) == $size_tmp ] ||
25007                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
25008         rm $dom $tmp
25009
25010         return 0
25011 }
25012 run_test 270a "DoM: basic functionality tests"
25013
25014 test_270b() {
25015         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25016                 skip "Need MDS version at least 2.10.55"
25017
25018         local dom=$DIR/$tdir/dom_file
25019         local max_size=1048576
25020
25021         mkdir -p $DIR/$tdir
25022         $LFS setstripe -E $max_size -L mdt $dom
25023
25024         # truncate over the limit
25025         $TRUNCATE $dom $(($max_size + 1)) &&
25026                 error "successful truncate over the maximum size"
25027         # write over the limit
25028         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
25029                 error "successful write over the maximum size"
25030         # append over the limit
25031         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
25032         echo "12345" >> $dom && error "successful append over the maximum size"
25033         rm $dom
25034
25035         return 0
25036 }
25037 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
25038
25039 test_270c() {
25040         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25041                 skip "Need MDS version at least 2.10.55"
25042
25043         mkdir -p $DIR/$tdir
25044         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25045
25046         # check files inherit DoM EA
25047         touch $DIR/$tdir/first
25048         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
25049                 error "bad pattern"
25050         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
25051                 error "bad stripe count"
25052         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
25053                 error "bad stripe size"
25054
25055         # check directory inherits DoM EA and uses it as default
25056         mkdir $DIR/$tdir/subdir
25057         touch $DIR/$tdir/subdir/second
25058         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
25059                 error "bad pattern in sub-directory"
25060         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
25061                 error "bad stripe count in sub-directory"
25062         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
25063                 error "bad stripe size in sub-directory"
25064         return 0
25065 }
25066 run_test 270c "DoM: DoM EA inheritance tests"
25067
25068 test_270d() {
25069         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25070                 skip "Need MDS version at least 2.10.55"
25071
25072         mkdir -p $DIR/$tdir
25073         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25074
25075         # inherit default DoM striping
25076         mkdir $DIR/$tdir/subdir
25077         touch $DIR/$tdir/subdir/f1
25078
25079         # change default directory striping
25080         $LFS setstripe -c 1 $DIR/$tdir/subdir
25081         touch $DIR/$tdir/subdir/f2
25082         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
25083                 error "wrong default striping in file 2"
25084         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
25085                 error "bad pattern in file 2"
25086         return 0
25087 }
25088 run_test 270d "DoM: change striping from DoM to RAID0"
25089
25090 test_270e() {
25091         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25092                 skip "Need MDS version at least 2.10.55"
25093
25094         mkdir -p $DIR/$tdir/dom
25095         mkdir -p $DIR/$tdir/norm
25096         DOMFILES=20
25097         NORMFILES=10
25098         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
25099         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
25100
25101         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
25102         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
25103
25104         # find DoM files by layout
25105         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
25106         [ $NUM -eq  $DOMFILES ] ||
25107                 error "lfs find -L: found $NUM, expected $DOMFILES"
25108         echo "Test 1: lfs find 20 DOM files by layout: OK"
25109
25110         # there should be 1 dir with default DOM striping
25111         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
25112         [ $NUM -eq  1 ] ||
25113                 error "lfs find -L: found $NUM, expected 1 dir"
25114         echo "Test 2: lfs find 1 DOM dir by layout: OK"
25115
25116         # find DoM files by stripe size
25117         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
25118         [ $NUM -eq  $DOMFILES ] ||
25119                 error "lfs find -S: found $NUM, expected $DOMFILES"
25120         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
25121
25122         # find files by stripe offset except DoM files
25123         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
25124         [ $NUM -eq  $NORMFILES ] ||
25125                 error "lfs find -i: found $NUM, expected $NORMFILES"
25126         echo "Test 5: lfs find no DOM files by stripe index: OK"
25127         return 0
25128 }
25129 run_test 270e "DoM: lfs find with DoM files test"
25130
25131 test_270f() {
25132         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25133                 skip "Need MDS version at least 2.10.55"
25134
25135         local mdtname=${FSNAME}-MDT0000-mdtlov
25136         local dom=$DIR/$tdir/dom_file
25137         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
25138                                                 lod.$mdtname.dom_stripesize)
25139         local dom_limit=131072
25140
25141         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
25142         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25143                                                 lod.$mdtname.dom_stripesize)
25144         [ ${dom_limit} -eq ${dom_current} ] ||
25145                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
25146
25147         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25148         $LFS setstripe -d $DIR/$tdir
25149         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
25150                 error "Can't set directory default striping"
25151
25152         # exceed maximum stripe size
25153         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25154                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
25155         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
25156                 error "Able to create DoM component size more than LOD limit"
25157
25158         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25159         dom_current=$(do_facet mds1 $LCTL get_param -n \
25160                                                 lod.$mdtname.dom_stripesize)
25161         [ 0 -eq ${dom_current} ] ||
25162                 error "Can't set zero DoM stripe limit"
25163         rm $dom
25164
25165         # attempt to create DoM file on server with disabled DoM should
25166         # remove DoM entry from layout and be succeed
25167         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
25168                 error "Can't create DoM file (DoM is disabled)"
25169         [ $($LFS getstripe -L $dom) == "mdt" ] &&
25170                 error "File has DoM component while DoM is disabled"
25171         rm $dom
25172
25173         # attempt to create DoM file with only DoM stripe should return error
25174         $LFS setstripe -E $dom_limit -L mdt $dom &&
25175                 error "Able to create DoM-only file while DoM is disabled"
25176
25177         # too low values to be aligned with smallest stripe size 64K
25178         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
25179         dom_current=$(do_facet mds1 $LCTL get_param -n \
25180                                                 lod.$mdtname.dom_stripesize)
25181         [ 30000 -eq ${dom_current} ] &&
25182                 error "Can set too small DoM stripe limit"
25183
25184         # 64K is a minimal stripe size in Lustre, expect limit of that size
25185         [ 65536 -eq ${dom_current} ] ||
25186                 error "Limit is not set to 64K but ${dom_current}"
25187
25188         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
25189         dom_current=$(do_facet mds1 $LCTL get_param -n \
25190                                                 lod.$mdtname.dom_stripesize)
25191         echo $dom_current
25192         [ 2147483648 -eq ${dom_current} ] &&
25193                 error "Can set too large DoM stripe limit"
25194
25195         do_facet mds1 $LCTL set_param -n \
25196                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
25197         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25198                 error "Can't create DoM component size after limit change"
25199         do_facet mds1 $LCTL set_param -n \
25200                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
25201         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25202                 error "Can't create DoM file after limit decrease"
25203         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25204                 error "Can create big DoM component after limit decrease"
25205         touch ${dom}_def ||
25206                 error "Can't create file with old default layout"
25207
25208         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25209         return 0
25210 }
25211 run_test 270f "DoM: maximum DoM stripe size checks"
25212
25213 test_270g() {
25214         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25215                 skip "Need MDS version at least 2.13.52"
25216         local dom=$DIR/$tdir/$tfile
25217
25218         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25219         local lodname=${FSNAME}-MDT0000-mdtlov
25220
25221         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25222         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25223         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25224         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25225
25226         local dom_limit=1024
25227         local dom_threshold="50%"
25228
25229         $LFS setstripe -d $DIR/$tdir
25230         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25231                 error "Can't set directory default striping"
25232
25233         do_facet mds1 $LCTL set_param -n \
25234                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25235         # set 0 threshold and create DOM file to change tunable stripesize
25236         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25237         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25238                 error "Failed to create $dom file"
25239         # now tunable dom_cur_stripesize should reach maximum
25240         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25241                                         lod.${lodname}.dom_stripesize_cur_kb)
25242         [[ $dom_current == $dom_limit ]] ||
25243                 error "Current DOM stripesize is not maximum"
25244         rm $dom
25245
25246         # set threshold for further tests
25247         do_facet mds1 $LCTL set_param -n \
25248                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25249         echo "DOM threshold is $dom_threshold free space"
25250         local dom_def
25251         local dom_set
25252         # Spoof bfree to exceed threshold
25253         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25254         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25255         for spfree in 40 20 0 15 30 55; do
25256                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25257                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25258                         error "Failed to create $dom file"
25259                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25260                                         lod.${lodname}.dom_stripesize_cur_kb)
25261                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25262                 [[ $dom_def != $dom_current ]] ||
25263                         error "Default stripe size was not changed"
25264                 if (( spfree > 0 )) ; then
25265                         dom_set=$($LFS getstripe -S $dom)
25266                         (( dom_set == dom_def * 1024 )) ||
25267                                 error "DOM component size is still old"
25268                 else
25269                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25270                                 error "DoM component is set with no free space"
25271                 fi
25272                 rm $dom
25273                 dom_current=$dom_def
25274         done
25275 }
25276 run_test 270g "DoM: default DoM stripe size depends on free space"
25277
25278 test_270h() {
25279         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25280                 skip "Need MDS version at least 2.13.53"
25281
25282         local mdtname=${FSNAME}-MDT0000-mdtlov
25283         local dom=$DIR/$tdir/$tfile
25284         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25285
25286         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25287         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25288
25289         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25290         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25291                 error "can't create OST file"
25292         # mirrored file with DOM entry in the second mirror
25293         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25294                 error "can't create mirror with DoM component"
25295
25296         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25297
25298         # DOM component in the middle and has other enries in the same mirror,
25299         # should succeed but lost DoM component
25300         $LFS setstripe --copy=${dom}_1 $dom ||
25301                 error "Can't create file from OST|DOM mirror layout"
25302         # check new file has no DoM layout after all
25303         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25304                 error "File has DoM component while DoM is disabled"
25305 }
25306 run_test 270h "DoM: DoM stripe removal when disabled on server"
25307
25308 test_270i() {
25309         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25310                 skip "Need MDS version at least 2.14.54"
25311
25312         mkdir $DIR/$tdir
25313         # DoM with plain layout
25314         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25315                 error "default plain layout with DoM must fail"
25316         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25317                 error "setstripe plain file layout with DoM must fail"
25318         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25319                 error "default DoM layout with bad striping must fail"
25320         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25321                 error "setstripe to DoM layout with bad striping must fail"
25322         return 0
25323 }
25324 run_test 270i "DoM: setting invalid DoM striping should fail"
25325
25326 test_270j() {
25327         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25328                 skip "Need MDS version at least 2.15.55.203"
25329
25330         local dom=$DIR/$tdir/$tfile
25331         local odv
25332         local ndv
25333
25334         mkdir -p $DIR/$tdir
25335
25336         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25337
25338         odv=$($LFS data_version $dom)
25339         chmod 666 $dom
25340         mv $dom ${dom}_moved
25341         link ${dom}_moved $dom
25342         setfattr -n user.attrx -v "some_attr" $dom
25343         ndv=$($LFS data_version $dom)
25344         (( $ndv == $odv )) ||
25345                 error "data version was changed by metadata operations"
25346
25347         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25348                 error "failed to write data into $dom"
25349         cancel_lru_locks mdc
25350         ndv=$($LFS data_version $dom)
25351         (( $ndv != $odv )) ||
25352                 error "data version wasn't changed on write"
25353
25354         odv=$ndv
25355         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25356         ndv=$($LFS data_version $dom)
25357         (( $ndv != $odv )) ||
25358                 error "data version wasn't changed on truncate down"
25359
25360         odv=$ndv
25361         $TRUNCATE $dom 25000
25362         ndv=$($LFS data_version $dom)
25363         (( $ndv != $odv )) ||
25364                 error "data version wasn't changed on truncate up"
25365
25366         # check also fallocate for ldiskfs
25367         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25368                 odv=$ndv
25369                 fallocate -l 1048576 $dom
25370                 ndv=$($LFS data_version $dom)
25371                 (( $ndv != $odv )) ||
25372                         error "data version wasn't changed on fallocate"
25373
25374                 odv=$ndv
25375                 fallocate -p --offset 4096 -l 4096 $dom
25376                 ndv=$($LFS data_version $dom)
25377                 (( $ndv != $odv )) ||
25378                         error "data version wasn't changed on fallocate punch"
25379         fi
25380 }
25381 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25382
25383 test_271a() {
25384         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25385                 skip "Need MDS version at least 2.10.55"
25386
25387         local dom=$DIR/$tdir/dom
25388
25389         mkdir -p $DIR/$tdir
25390
25391         $LFS setstripe -E 1024K -L mdt $dom
25392
25393         lctl set_param -n mdc.*.stats=clear
25394         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25395         cat $dom > /dev/null
25396         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25397         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25398         ls $dom
25399         rm -f $dom
25400 }
25401 run_test 271a "DoM: data is cached for read after write"
25402
25403 test_271b() {
25404         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25405                 skip "Need MDS version at least 2.10.55"
25406
25407         local dom=$DIR/$tdir/dom
25408
25409         mkdir -p $DIR/$tdir
25410
25411         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25412
25413         lctl set_param -n mdc.*.stats=clear
25414         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25415         cancel_lru_locks mdc
25416         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25417         # second stat to check size is cached on client
25418         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25419         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25420         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25421         rm -f $dom
25422 }
25423 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25424
25425 test_271ba() {
25426         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25427                 skip "Need MDS version at least 2.10.55"
25428
25429         local dom=$DIR/$tdir/dom
25430
25431         mkdir -p $DIR/$tdir
25432
25433         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25434
25435         lctl set_param -n mdc.*.stats=clear
25436         lctl set_param -n osc.*.stats=clear
25437         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25438         cancel_lru_locks mdc
25439         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25440         # second stat to check size is cached on client
25441         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25442         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25443         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25444         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25445         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25446         rm -f $dom
25447 }
25448 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25449
25450
25451 get_mdc_stats() {
25452         local mdtidx=$1
25453         local param=$2
25454         local mdt=MDT$(printf %04x $mdtidx)
25455
25456         if [ -z $param ]; then
25457                 lctl get_param -n mdc.*$mdt*.stats
25458         else
25459                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25460         fi
25461 }
25462
25463 test_271c() {
25464         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25465                 skip "Need MDS version at least 2.10.55"
25466
25467         local dom=$DIR/$tdir/dom
25468
25469         mkdir -p $DIR/$tdir
25470
25471         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25472
25473         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25474         local facet=mds$((mdtidx + 1))
25475
25476         cancel_lru_locks mdc
25477         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25478         createmany -o $dom 1000
25479         lctl set_param -n mdc.*.stats=clear
25480         smalliomany -w $dom 1000 200
25481         get_mdc_stats $mdtidx
25482         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25483         # Each file has 1 open, 1 IO enqueues, total 2000
25484         # but now we have also +1 getxattr for security.capability, total 3000
25485         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25486         unlinkmany $dom 1000
25487
25488         cancel_lru_locks mdc
25489         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25490         createmany -o $dom 1000
25491         lctl set_param -n mdc.*.stats=clear
25492         smalliomany -w $dom 1000 200
25493         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25494         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25495         # for OPEN and IO lock.
25496         [ $((enq - enq_2)) -ge 1000 ] ||
25497                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25498         unlinkmany $dom 1000
25499         return 0
25500 }
25501 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25502
25503 cleanup_271def_tests() {
25504         trap 0
25505         rm -f $1
25506 }
25507
25508 test_271d() {
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=1000 count=1
25524         dd if=$tmp of=$dom bs=1000 count=1
25525         cancel_lru_locks mdc
25526
25527         cat /etc/hosts >> $tmp
25528         lctl set_param -n mdc.*.stats=clear
25529
25530         # append data to the same file it should update local page
25531         echo "Append to the same page"
25532         cat /etc/hosts >> $dom
25533         local num=$(get_mdc_stats $mdtidx ost_read)
25534         local ra=$(get_mdc_stats $mdtidx req_active)
25535         local rw=$(get_mdc_stats $mdtidx req_waittime)
25536
25537         [ -z $num ] || error "$num READ RPC occured"
25538         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25539         echo "... DONE"
25540
25541         # compare content
25542         cmp $tmp $dom || error "file miscompare"
25543
25544         cancel_lru_locks mdc
25545         lctl set_param -n mdc.*.stats=clear
25546
25547         echo "Open and read file"
25548         cat $dom > /dev/null
25549         local num=$(get_mdc_stats $mdtidx ost_read)
25550         local ra=$(get_mdc_stats $mdtidx req_active)
25551         local rw=$(get_mdc_stats $mdtidx req_waittime)
25552
25553         [ -z $num ] || error "$num READ RPC occured"
25554         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25555         echo "... DONE"
25556
25557         # compare content
25558         cmp $tmp $dom || error "file miscompare"
25559
25560         return 0
25561 }
25562 run_test 271d "DoM: read on open (1K file in reply buffer)"
25563
25564 test_271f() {
25565         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25566                 skip "Need MDS version at least 2.10.57"
25567
25568         local dom=$DIR/$tdir/dom
25569         local tmp=$TMP/$tfile
25570         trap "cleanup_271def_tests $tmp" EXIT
25571
25572         mkdir -p $DIR/$tdir
25573
25574         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25575
25576         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25577
25578         cancel_lru_locks mdc
25579         dd if=/dev/urandom of=$tmp bs=265000 count=1
25580         dd if=$tmp of=$dom bs=265000 count=1
25581         cancel_lru_locks mdc
25582         cat /etc/hosts >> $tmp
25583         lctl set_param -n mdc.*.stats=clear
25584
25585         echo "Append to the same page"
25586         cat /etc/hosts >> $dom
25587         local num=$(get_mdc_stats $mdtidx ost_read)
25588         local ra=$(get_mdc_stats $mdtidx req_active)
25589         local rw=$(get_mdc_stats $mdtidx req_waittime)
25590
25591         [ -z $num ] || error "$num READ RPC occured"
25592         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25593         echo "... DONE"
25594
25595         # compare content
25596         cmp $tmp $dom || error "file miscompare"
25597
25598         cancel_lru_locks mdc
25599         lctl set_param -n mdc.*.stats=clear
25600
25601         echo "Open and read file"
25602         cat $dom > /dev/null
25603         local num=$(get_mdc_stats $mdtidx ost_read)
25604         local ra=$(get_mdc_stats $mdtidx req_active)
25605         local rw=$(get_mdc_stats $mdtidx req_waittime)
25606
25607         [ -z $num ] && num=0
25608         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25609         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25610         echo "... DONE"
25611
25612         # compare content
25613         cmp $tmp $dom || error "file miscompare"
25614
25615         return 0
25616 }
25617 run_test 271f "DoM: read on open (200K file and read tail)"
25618
25619 test_271g() {
25620         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25621                 skip "Skipping due to old client or server version"
25622
25623         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25624         # to get layout
25625         $CHECKSTAT -t file $DIR1/$tfile
25626
25627         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25628         MULTIOP_PID=$!
25629         sleep 1
25630         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25631         $LCTL set_param fail_loc=0x80000314
25632         rm $DIR1/$tfile || error "Unlink fails"
25633         RC=$?
25634         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25635         [ $RC -eq 0 ] || error "Failed write to stale object"
25636 }
25637 run_test 271g "Discard DoM data vs client flush race"
25638
25639 test_272a() {
25640         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25641                 skip "Need MDS version at least 2.11.50"
25642
25643         local dom=$DIR/$tdir/dom
25644         mkdir -p $DIR/$tdir
25645
25646         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25647         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25648                 error "failed to write data into $dom"
25649         local old_md5=$(md5sum $dom)
25650
25651         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25652                 error "failed to migrate to the same DoM component"
25653
25654         local new_md5=$(md5sum $dom)
25655
25656         [ "$old_md5" == "$new_md5" ] ||
25657                 error "md5sum differ: $old_md5, $new_md5"
25658
25659         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25660                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25661 }
25662 run_test 272a "DoM migration: new layout with the same DOM component"
25663
25664 test_272b() {
25665         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25666                 skip "Need MDS version at least 2.11.50"
25667
25668         local dom=$DIR/$tdir/dom
25669         mkdir -p $DIR/$tdir
25670         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25671         stack_trap "rm -rf $DIR/$tdir"
25672
25673         local mdtidx=$($LFS getstripe -m $dom)
25674         local mdtname=MDT$(printf %04x $mdtidx)
25675         local facet=mds$((mdtidx + 1))
25676
25677         local mdtfree1=$(do_facet $facet \
25678                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25679         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25680                 error "failed to write data into $dom"
25681         local old_md5=$(md5sum $dom)
25682         cancel_lru_locks mdc
25683         local mdtfree1=$(do_facet $facet \
25684                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25685
25686         $LFS migrate -c2 $dom ||
25687                 error "failed to migrate to the new composite layout"
25688         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25689                 error "MDT stripe was not removed"
25690         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25691                 error "$dir1 shouldn't have DATAVER EA"
25692
25693         cancel_lru_locks mdc
25694         local new_md5=$(md5sum $dom)
25695         [ "$old_md5" == "$new_md5" ] ||
25696                 error "$old_md5 != $new_md5"
25697
25698         # Skip free space checks with ZFS
25699         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25700                 local mdtfree2=$(do_facet $facet \
25701                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25702                 [ $mdtfree2 -gt $mdtfree1 ] ||
25703                         error "MDT space is not freed after migration"
25704         fi
25705         return 0
25706 }
25707 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25708
25709 test_272c() {
25710         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25711                 skip "Need MDS version at least 2.11.50"
25712
25713         local dom=$DIR/$tdir/$tfile
25714         mkdir -p $DIR/$tdir
25715         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25716         stack_trap "rm -rf $DIR/$tdir"
25717
25718         local mdtidx=$($LFS getstripe -m $dom)
25719         local mdtname=MDT$(printf %04x $mdtidx)
25720         local facet=mds$((mdtidx + 1))
25721
25722         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25723                 error "failed to write data into $dom"
25724         local old_md5=$(md5sum $dom)
25725         cancel_lru_locks mdc
25726         local mdtfree1=$(do_facet $facet \
25727                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25728
25729         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25730                 error "failed to migrate to the new composite layout"
25731         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25732                 error "MDT stripe was not removed"
25733
25734         cancel_lru_locks mdc
25735         local new_md5=$(md5sum $dom)
25736         [ "$old_md5" == "$new_md5" ] ||
25737                 error "$old_md5 != $new_md5"
25738
25739         # Skip free space checks with ZFS
25740         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25741                 local mdtfree2=$(do_facet $facet \
25742                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25743                 [ $mdtfree2 -gt $mdtfree1 ] ||
25744                         error "MDS space is not freed after migration"
25745         fi
25746         return 0
25747 }
25748 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25749
25750 test_272d() {
25751         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25752                 skip "Need MDS version at least 2.12.55"
25753
25754         local dom=$DIR/$tdir/$tfile
25755         mkdir -p $DIR/$tdir
25756         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25757
25758         local mdtidx=$($LFS getstripe -m $dom)
25759         local mdtname=MDT$(printf %04x $mdtidx)
25760         local facet=mds$((mdtidx + 1))
25761
25762         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25763                 error "failed to write data into $dom"
25764         local old_md5=$(md5sum $dom)
25765         cancel_lru_locks mdc
25766         local mdtfree1=$(do_facet $facet \
25767                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25768
25769         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25770                 error "failed mirroring to the new composite layout"
25771         $LFS mirror resync $dom ||
25772                 error "failed mirror resync"
25773         $LFS mirror split --mirror-id 1 -d $dom ||
25774                 error "failed mirror split"
25775
25776         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25777                 error "MDT stripe was not removed"
25778
25779         cancel_lru_locks mdc
25780         local new_md5=$(md5sum $dom)
25781         [ "$old_md5" == "$new_md5" ] ||
25782                 error "$old_md5 != $new_md5"
25783
25784         # Skip free space checks with ZFS
25785         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25786                 local mdtfree2=$(do_facet $facet \
25787                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25788                 [ $mdtfree2 -gt $mdtfree1 ] ||
25789                         error "MDS space is not freed after DOM mirror deletion"
25790         fi
25791         return 0
25792 }
25793 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25794
25795 test_272e() {
25796         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25797                 skip "Need MDS version at least 2.12.55"
25798
25799         local dom=$DIR/$tdir/$tfile
25800         mkdir -p $DIR/$tdir
25801         $LFS setstripe -c 2 $dom
25802
25803         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25804                 error "failed to write data into $dom"
25805         local old_md5=$(md5sum $dom)
25806         cancel_lru_locks
25807
25808         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25809                 error "failed mirroring to the DOM layout"
25810         $LFS mirror resync $dom ||
25811                 error "failed mirror resync"
25812         $LFS mirror split --mirror-id 1 -d $dom ||
25813                 error "failed mirror split"
25814
25815         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25816                 error "MDT stripe wasn't set"
25817
25818         cancel_lru_locks
25819         local new_md5=$(md5sum $dom)
25820         [ "$old_md5" == "$new_md5" ] ||
25821                 error "$old_md5 != $new_md5"
25822
25823         return 0
25824 }
25825 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25826
25827 test_272f() {
25828         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25829                 skip "Need MDS version at least 2.12.55"
25830
25831         local dom=$DIR/$tdir/$tfile
25832         mkdir -p $DIR/$tdir
25833         $LFS setstripe -c 2 $dom
25834
25835         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25836                 error "failed to write data into $dom"
25837         local old_md5=$(md5sum $dom)
25838         cancel_lru_locks
25839
25840         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25841                 error "failed migrating to the DOM file"
25842
25843         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25844                 error "MDT stripe wasn't set"
25845
25846         cancel_lru_locks
25847         local new_md5=$(md5sum $dom)
25848         [ "$old_md5" != "$new_md5" ] &&
25849                 error "$old_md5 != $new_md5"
25850
25851         return 0
25852 }
25853 run_test 272f "DoM migration: OST-striped file to DOM file"
25854
25855 test_273a() {
25856         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25857                 skip "Need MDS version at least 2.11.50"
25858
25859         # Layout swap cannot be done if either file has DOM component,
25860         # this will never be supported, migration should be used instead
25861
25862         local dom=$DIR/$tdir/$tfile
25863         mkdir -p $DIR/$tdir
25864
25865         $LFS setstripe -c2 ${dom}_plain
25866         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25867         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25868                 error "can swap layout with DoM component"
25869         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25870                 error "can swap layout with DoM component"
25871
25872         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25873         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25874                 error "can swap layout with DoM component"
25875         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25876                 error "can swap layout with DoM component"
25877         return 0
25878 }
25879 run_test 273a "DoM: layout swapping should fail with DOM"
25880
25881 test_273b() {
25882         mkdir -p $DIR/$tdir
25883         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25884
25885 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25886         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25887
25888         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25889 }
25890 run_test 273b "DoM: race writeback and object destroy"
25891
25892 test_273c() {
25893         mkdir -p $DIR/$tdir
25894         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25895
25896         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25897         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25898
25899         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25900 }
25901 run_test 273c "race writeback and object destroy"
25902
25903 test_275() {
25904         remote_ost_nodsh && skip "remote OST with nodsh"
25905         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25906                 skip "Need OST version >= 2.10.57"
25907
25908         local file=$DIR/$tfile
25909         local oss
25910
25911         oss=$(comma_list $(osts_nodes))
25912
25913         dd if=/dev/urandom of=$file bs=1M count=2 ||
25914                 error "failed to create a file"
25915         stack_trap "rm -f $file"
25916         cancel_lru_locks osc
25917
25918         #lock 1
25919         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25920                 error "failed to read a file"
25921
25922 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25923         $LCTL set_param fail_loc=0x8000031f
25924
25925         cancel_lru_locks osc &
25926         sleep 1
25927
25928 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25929         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25930         #IO takes another lock, but matches the PENDING one
25931         #and places it to the IO RPC
25932         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25933                 error "failed to read a file with PENDING lock"
25934 }
25935 run_test 275 "Read on a canceled duplicate lock"
25936
25937 test_276() {
25938         remote_ost_nodsh && skip "remote OST with nodsh"
25939         local pid
25940
25941         do_facet ost1 "(while true; do \
25942                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25943                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25944         pid=$!
25945
25946         for LOOP in $(seq 20); do
25947                 stop ost1
25948                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25949         done
25950         kill -9 $pid
25951         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25952                 rm $TMP/sanity_276_pid"
25953 }
25954 run_test 276 "Race between mount and obd_statfs"
25955
25956 test_277() {
25957         $LCTL set_param ldlm.namespaces.*.lru_size=0
25958         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25959         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25960                           awk '/^used_mb/ { print $2 }')
25961         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25963                 oflag=direct conv=notrunc
25964         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25965                     awk '/^used_mb/ { print $2 }')
25966         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25967 }
25968 run_test 277 "Direct IO shall drop page cache"
25969
25970 test_278() {
25971         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25972         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25973         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25974                 skip "needs the same host for mdt1 mdt2" && return
25975
25976         local pid1
25977         local pid2
25978
25979 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25980         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25981         stop mds2 &
25982         pid2=$!
25983
25984         stop mds1
25985
25986         echo "Starting MDTs"
25987         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25988         wait $pid2
25989 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25990 #will return NULL
25991         do_facet mds2 $LCTL set_param fail_loc=0
25992
25993         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25994         wait_recovery_complete mds2
25995 }
25996 run_test 278 "Race starting MDS between MDTs stop/start"
25997
25998 test_280() {
25999         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
26000                 skip "Need MGS version at least 2.13.52"
26001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26002         combined_mgs_mds || skip "needs combined MGS/MDT"
26003
26004         umount_client $MOUNT
26005 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
26006         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
26007
26008         mount_client $MOUNT &
26009         sleep 1
26010         stop mgs || error "stop mgs failed"
26011         #for a race mgs would crash
26012         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
26013         # make sure we unmount client before remounting
26014         wait
26015         umount_client $MOUNT
26016         mount_client $MOUNT || error "mount client failed"
26017 }
26018 run_test 280 "Race between MGS umount and client llog processing"
26019
26020 cleanup_test_300() {
26021         trap 0
26022         umask $SAVE_UMASK
26023 }
26024
26025 test_striped_dir() {
26026         local mdt_index=$1
26027         local stripe_count=$2
26028         local overstriping=$3
26029         local stripe_index
26030         local getstripe_count
26031
26032         mkdir -p $DIR/$tdir
26033
26034         SAVE_UMASK=$(umask)
26035         trap cleanup_test_300 RETURN EXIT
26036
26037         if [ -z $overstriping ]; then
26038                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
26039                                         -o 755 $DIR/$tdir/striped_dir ||
26040                         error "set striped dir error"
26041         else
26042                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
26043                                         -o 755 $DIR/$tdir/striped_dir ||
26044                         error "set striped dir error"
26045         fi
26046
26047         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
26048         [ "$mode" = "755" ] || error "expect 755 got $mode"
26049
26050         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
26051                 error "getdirstripe failed"
26052         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
26053         if [ "$getstripe_count" != "$stripe_count" ]; then
26054                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
26055         fi
26056         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
26057         if [ "$getstripe_count" != "$stripe_count" ]; then
26058                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
26059         fi
26060
26061         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
26062         if [ "$stripe_index" != "$mdt_index" ]; then
26063                 error "stripe_index is $stripe_index, expect $mdt_index"
26064         fi
26065
26066         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
26067                 error "nlink error after create striped dir"
26068
26069         mkdir $DIR/$tdir/striped_dir/a
26070         mkdir $DIR/$tdir/striped_dir/b
26071
26072         stat $DIR/$tdir/striped_dir/a ||
26073                 error "create dir under striped dir failed"
26074         stat $DIR/$tdir/striped_dir/b ||
26075                 error "create dir under striped dir failed"
26076
26077         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
26078                 error "nlink error after mkdir"
26079
26080         rmdir $DIR/$tdir/striped_dir/a
26081         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
26082                 error "nlink error after rmdir"
26083
26084         rmdir $DIR/$tdir/striped_dir/b
26085         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
26086                 error "nlink error after rmdir"
26087
26088         chattr +i $DIR/$tdir/striped_dir
26089         createmany -o $DIR/$tdir/striped_dir/f 10 &&
26090                 error "immutable flags not working under striped dir!"
26091         chattr -i $DIR/$tdir/striped_dir
26092
26093         rmdir $DIR/$tdir/striped_dir ||
26094                 error "rmdir striped dir error"
26095
26096         cleanup_test_300
26097
26098         true
26099 }
26100
26101 test_300a() {
26102         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26103                 skip "skipped for lustre < 2.7.0"
26104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26106
26107         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
26108         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
26109 }
26110 run_test 300a "basic striped dir sanity test"
26111
26112 test_300b() {
26113         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26114                 skip "skipped for lustre < 2.7.0"
26115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26116         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26117
26118         local i
26119         local mtime1
26120         local mtime2
26121         local mtime3
26122
26123         test_mkdir $DIR/$tdir || error "mkdir fail"
26124         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26125                 error "set striped dir error"
26126         for i in {0..9}; do
26127                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
26128                 sleep 1
26129                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
26130                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
26131                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
26132                 sleep 1
26133                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
26134                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
26135                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
26136         done
26137         true
26138 }
26139 run_test 300b "check ctime/mtime for striped dir"
26140
26141 test_300c() {
26142         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26143                 skip "skipped for lustre < 2.7.0"
26144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26145         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26146
26147         local file_count
26148
26149         mkdir_on_mdt0 $DIR/$tdir
26150         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
26151                 error "set striped dir error"
26152
26153         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
26154                 error "chown striped dir failed"
26155
26156         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
26157                 error "create 5k files failed"
26158
26159         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
26160
26161         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
26162
26163         rm -rf $DIR/$tdir
26164 }
26165 run_test 300c "chown && check ls under striped directory"
26166
26167 test_300d() {
26168         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26169                 skip "skipped for lustre < 2.7.0"
26170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26171         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26172
26173         local stripe_count
26174         local file
26175
26176         mkdir -p $DIR/$tdir
26177         $LFS setstripe -c 2 $DIR/$tdir
26178
26179         #local striped directory
26180         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26181                 error "set striped dir error"
26182         #look at the directories for debug purposes
26183         ls -l $DIR/$tdir
26184         $LFS getdirstripe $DIR/$tdir
26185         ls -l $DIR/$tdir/striped_dir
26186         $LFS getdirstripe $DIR/$tdir/striped_dir
26187         createmany -o $DIR/$tdir/striped_dir/f 10 ||
26188                 error "create 10 files failed"
26189
26190         #remote striped directory
26191         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
26192                 error "set striped dir error"
26193         #look at the directories for debug purposes
26194         ls -l $DIR/$tdir
26195         $LFS getdirstripe $DIR/$tdir
26196         ls -l $DIR/$tdir/remote_striped_dir
26197         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
26198         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
26199                 error "create 10 files failed"
26200
26201         for file in $(find $DIR/$tdir); do
26202                 stripe_count=$($LFS getstripe -c $file)
26203                 [ $stripe_count -eq 2 ] ||
26204                         error "wrong stripe $stripe_count for $file"
26205         done
26206
26207         rm -rf $DIR/$tdir
26208 }
26209 run_test 300d "check default stripe under striped directory"
26210
26211 test_300e() {
26212         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26213                 skip "Need MDS version at least 2.7.55"
26214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26215         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26216
26217         local stripe_count
26218         local file
26219
26220         mkdir -p $DIR/$tdir
26221
26222         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26223                 error "set striped dir error"
26224
26225         touch $DIR/$tdir/striped_dir/a
26226         touch $DIR/$tdir/striped_dir/b
26227         touch $DIR/$tdir/striped_dir/c
26228
26229         mkdir $DIR/$tdir/striped_dir/dir_a
26230         mkdir $DIR/$tdir/striped_dir/dir_b
26231         mkdir $DIR/$tdir/striped_dir/dir_c
26232
26233         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26234                 error "set striped adir under striped dir error"
26235
26236         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26237                 error "set striped bdir under striped dir error"
26238
26239         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26240                 error "set striped cdir under striped dir error"
26241
26242         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26243                 error "rename dir under striped dir fails"
26244
26245         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26246                 error "rename dir under different stripes fails"
26247
26248         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26249                 error "rename file under striped dir should succeed"
26250
26251         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26252                 error "rename dir under striped dir should succeed"
26253
26254         rm -rf $DIR/$tdir
26255 }
26256 run_test 300e "check rename under striped directory"
26257
26258 test_300f() {
26259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26261         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26262                 skip "Need MDS version at least 2.7.55"
26263
26264         local stripe_count
26265         local file
26266
26267         rm -rf $DIR/$tdir
26268         mkdir -p $DIR/$tdir
26269
26270         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26271                 error "set striped dir error"
26272
26273         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26274                 error "set striped dir error"
26275
26276         touch $DIR/$tdir/striped_dir/a
26277         mkdir $DIR/$tdir/striped_dir/dir_a
26278         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26279                 error "create striped dir under striped dir fails"
26280
26281         touch $DIR/$tdir/striped_dir1/b
26282         mkdir $DIR/$tdir/striped_dir1/dir_b
26283         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26284                 error "create striped dir under striped dir fails"
26285
26286         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26287                 error "rename dir under different striped dir should fail"
26288
26289         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26290                 error "rename striped dir under diff striped dir should fail"
26291
26292         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26293                 error "rename file under diff striped dirs fails"
26294
26295         rm -rf $DIR/$tdir
26296 }
26297 run_test 300f "check rename cross striped directory"
26298
26299 test_300_check_default_striped_dir()
26300 {
26301         local dirname=$1
26302         local default_count=$2
26303         local default_index=$3
26304         local stripe_count
26305         local stripe_index
26306         local dir_stripe_index
26307         local dir
26308
26309         echo "checking $dirname $default_count $default_index"
26310         $LFS setdirstripe -D -c $default_count -i $default_index \
26311                                 -H all_char $DIR/$tdir/$dirname ||
26312                 error "set default stripe on striped dir error"
26313         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26314         [ $stripe_count -eq $default_count ] ||
26315                 error "expect $default_count get $stripe_count for $dirname"
26316
26317         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26318         [ $stripe_index -eq $default_index ] ||
26319                 error "expect $default_index get $stripe_index for $dirname"
26320
26321         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26322                                                 error "create dirs failed"
26323
26324         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26325         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26326         for dir in $(find $DIR/$tdir/$dirname/*); do
26327                 stripe_count=$($LFS getdirstripe -c $dir)
26328                 (( $stripe_count == $default_count )) ||
26329                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26330                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26331                 error "stripe count $default_count != $stripe_count for $dir"
26332
26333                 stripe_index=$($LFS getdirstripe -i $dir)
26334                 [ $default_index -eq -1 ] ||
26335                         [ $stripe_index -eq $default_index ] ||
26336                         error "$stripe_index != $default_index for $dir"
26337
26338                 #check default stripe
26339                 stripe_count=$($LFS getdirstripe -D -c $dir)
26340                 [ $stripe_count -eq $default_count ] ||
26341                 error "default count $default_count != $stripe_count for $dir"
26342
26343                 stripe_index=$($LFS getdirstripe -D -i $dir)
26344                 [ $stripe_index -eq $default_index ] ||
26345                 error "default index $default_index != $stripe_index for $dir"
26346         done
26347         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26348 }
26349
26350 test_300g() {
26351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26352         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26353                 skip "Need MDS version at least 2.7.55"
26354
26355         local dir
26356         local stripe_count
26357         local stripe_index
26358
26359         mkdir_on_mdt0 $DIR/$tdir
26360         mkdir $DIR/$tdir/normal_dir
26361
26362         #Checking when client cache stripe index
26363         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26364         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26365                 error "create striped_dir failed"
26366
26367         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26368                 error "create dir0 fails"
26369         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26370         [ $stripe_index -eq 0 ] ||
26371                 error "dir0 expect index 0 got $stripe_index"
26372
26373         mkdir $DIR/$tdir/striped_dir/dir1 ||
26374                 error "create dir1 fails"
26375         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26376         [ $stripe_index -eq 1 ] ||
26377                 error "dir1 expect index 1 got $stripe_index"
26378
26379         #check default stripe count/stripe index
26380         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26381         test_300_check_default_striped_dir normal_dir 1 0
26382         test_300_check_default_striped_dir normal_dir -1 1
26383         test_300_check_default_striped_dir normal_dir 2 -1
26384
26385         #delete default stripe information
26386         echo "delete default stripeEA"
26387         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26388                 error "set default stripe on striped dir error"
26389
26390         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26391         for dir in $(find $DIR/$tdir/normal_dir/*); do
26392                 stripe_count=$($LFS getdirstripe -c $dir)
26393                 [ $stripe_count -eq 0 ] ||
26394                         error "expect 1 get $stripe_count for $dir"
26395         done
26396 }
26397 run_test 300g "check default striped directory for normal directory"
26398
26399 test_300h() {
26400         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26401         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26402                 skip "Need MDS version at least 2.7.55"
26403
26404         local dir
26405         local stripe_count
26406
26407         mkdir $DIR/$tdir
26408         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26409                 error "set striped dir error"
26410
26411         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26412         test_300_check_default_striped_dir striped_dir 1 0
26413         test_300_check_default_striped_dir striped_dir -1 1
26414         test_300_check_default_striped_dir striped_dir 2 -1
26415
26416         #delete default stripe information
26417         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26418                 error "set default stripe on striped dir error"
26419
26420         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26421         for dir in $(find $DIR/$tdir/striped_dir/*); do
26422                 stripe_count=$($LFS getdirstripe -c $dir)
26423                 [ $stripe_count -eq 0 ] ||
26424                         error "expect 1 get $stripe_count for $dir"
26425         done
26426 }
26427 run_test 300h "check default striped directory for striped directory"
26428
26429 test_300i() {
26430         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26431         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26432         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26433                 skip "Need MDS version at least 2.7.55"
26434
26435         local stripe_count
26436         local file
26437
26438         mkdir $DIR/$tdir
26439
26440         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26441                 error "set striped dir error"
26442
26443         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26444                 error "create files under striped dir failed"
26445
26446         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26447                 error "set striped hashdir error"
26448
26449         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26450                 error "create dir0 under hash dir failed"
26451         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26452                 error "create dir1 under hash dir failed"
26453         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26454                 error "create dir2 under hash dir failed"
26455
26456         # unfortunately, we need to umount to clear dir layout cache for now
26457         # once we fully implement dir layout, we can drop this
26458         umount_client $MOUNT || error "umount failed"
26459         mount_client $MOUNT || error "mount failed"
26460
26461         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26462         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26463         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26464
26465         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26466                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26467                         error "create crush2 dir $tdir/hashdir/d3 failed"
26468                 $LFS find -H crush2 $DIR/$tdir/hashdir
26469                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26470                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26471
26472                 # mkdir with an invalid hash type (hash=fail_val) from client
26473                 # should be replaced on MDS with a valid (default) hash type
26474                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26475                 $LCTL set_param fail_loc=0x1901 fail_val=99
26476                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26477
26478                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26479                 local expect=$(do_facet mds1 \
26480                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26481                 [[ $hash == $expect ]] ||
26482                         error "d99 hash '$hash' != expected hash '$expect'"
26483         fi
26484
26485         #set the stripe to be unknown hash type on read
26486         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26487         $LCTL set_param fail_loc=0x1901 fail_val=99
26488         for ((i = 0; i < 10; i++)); do
26489                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26490                         error "stat f-$i failed"
26491                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26492         done
26493
26494         touch $DIR/$tdir/striped_dir/f0 &&
26495                 error "create under striped dir with unknown hash should fail"
26496
26497         $LCTL set_param fail_loc=0
26498
26499         umount_client $MOUNT || error "umount failed"
26500         mount_client $MOUNT || error "mount failed"
26501
26502         return 0
26503 }
26504 run_test 300i "client handle unknown hash type striped directory"
26505
26506 test_300j() {
26507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26509         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26510                 skip "Need MDS version at least 2.7.55"
26511
26512         local stripe_count
26513         local file
26514
26515         mkdir $DIR/$tdir
26516
26517         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26518         $LCTL set_param fail_loc=0x1702
26519         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26520                 error "set striped dir error"
26521
26522         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26523                 error "create files under striped dir failed"
26524
26525         $LCTL set_param fail_loc=0
26526
26527         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26528
26529         return 0
26530 }
26531 run_test 300j "test large update record"
26532
26533 test_300k() {
26534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26535         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26536         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26537                 skip "Need MDS version at least 2.7.55"
26538
26539         # this test needs a huge transaction
26540         local kb
26541         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26542              osd*.$FSNAME-MDT0000.kbytestotal")
26543         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26544
26545         local stripe_count
26546         local file
26547
26548         mkdir $DIR/$tdir
26549
26550         #define OBD_FAIL_LARGE_STRIPE   0x1703
26551         $LCTL set_param fail_loc=0x1703
26552         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26553                 error "set striped dir error"
26554         $LCTL set_param fail_loc=0
26555
26556         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26557                 error "getstripeddir fails"
26558         rm -rf $DIR/$tdir/striped_dir ||
26559                 error "unlink striped dir fails"
26560
26561         return 0
26562 }
26563 run_test 300k "test large striped directory"
26564
26565 test_300l() {
26566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26568         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26569                 skip "Need MDS version at least 2.7.55"
26570
26571         local stripe_index
26572
26573         test_mkdir -p $DIR/$tdir/striped_dir
26574         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26575                         error "chown $RUNAS_ID failed"
26576         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26577                 error "set default striped dir failed"
26578
26579         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26580         $LCTL set_param fail_loc=0x80000158
26581         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26582
26583         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26584         [ $stripe_index -eq 1 ] ||
26585                 error "expect 1 get $stripe_index for $dir"
26586 }
26587 run_test 300l "non-root user to create dir under striped dir with stale layout"
26588
26589 test_300m() {
26590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26591         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26592         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26593                 skip "Need MDS version at least 2.7.55"
26594
26595         mkdir -p $DIR/$tdir/striped_dir
26596         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26597                 error "set default stripes dir error"
26598
26599         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26600
26601         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26602         [ $stripe_count -eq 0 ] ||
26603                         error "expect 0 get $stripe_count for a"
26604
26605         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26606                 error "set default stripes dir error"
26607
26608         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26609
26610         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26611         [ $stripe_count -eq 0 ] ||
26612                         error "expect 0 get $stripe_count for b"
26613
26614         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26615                 error "set default stripes dir error"
26616
26617         mkdir $DIR/$tdir/striped_dir/c &&
26618                 error "default stripe_index is invalid, mkdir c should fails"
26619
26620         rm -rf $DIR/$tdir || error "rmdir fails"
26621 }
26622 run_test 300m "setstriped directory on single MDT FS"
26623
26624 cleanup_300n() {
26625         local list=$(comma_list $(mdts_nodes))
26626
26627         trap 0
26628         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26629 }
26630
26631 test_300n() {
26632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26633         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26634         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26635                 skip "Need MDS version at least 2.7.55"
26636         remote_mds_nodsh && skip "remote MDS with nodsh"
26637
26638         local stripe_index
26639         local list=$(comma_list $(mdts_nodes))
26640
26641         trap cleanup_300n RETURN EXIT
26642         mkdir -p $DIR/$tdir
26643         chmod 777 $DIR/$tdir
26644         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26645                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26646                 error "create striped dir succeeds with gid=0"
26647
26648         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26649         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26650                 error "create striped dir fails with gid=-1"
26651
26652         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26653         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26654                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26655                 error "set default striped dir succeeds with gid=0"
26656
26657
26658         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26659         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26660                 error "set default striped dir fails with gid=-1"
26661
26662
26663         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26664         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26665                                         error "create test_dir fails"
26666         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26667                                         error "create test_dir1 fails"
26668         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26669                                         error "create test_dir2 fails"
26670         cleanup_300n
26671 }
26672 run_test 300n "non-root user to create dir under striped dir with default EA"
26673
26674 test_300o() {
26675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26677         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26678                 skip "Need MDS version at least 2.7.55"
26679
26680         local numfree1
26681         local numfree2
26682
26683         mkdir -p $DIR/$tdir
26684
26685         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26686         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26687         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26688                 skip "not enough free inodes $numfree1 $numfree2"
26689         fi
26690
26691         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26692         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26693         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26694                 skip "not enough free space $numfree1 $numfree2"
26695         fi
26696
26697         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26698                 error "setdirstripe fails"
26699
26700         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26701                 error "create dirs fails"
26702
26703         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26704         ls $DIR/$tdir/striped_dir > /dev/null ||
26705                 error "ls striped dir fails"
26706         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26707                 error "unlink big striped dir fails"
26708 }
26709 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26710
26711 test_300p() {
26712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26714         remote_mds_nodsh && skip "remote MDS with nodsh"
26715
26716         mkdir_on_mdt0 $DIR/$tdir
26717
26718         #define OBD_FAIL_OUT_ENOSPC     0x1704
26719         do_facet mds2 lctl set_param fail_loc=0x80001704
26720         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26721                  && error "create striped directory should fail"
26722
26723         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26724
26725         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26726         true
26727 }
26728 run_test 300p "create striped directory without space"
26729
26730 test_300q() {
26731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26732         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26733
26734         local fd=$(free_fd)
26735         local cmd="exec $fd<$tdir"
26736         cd $DIR
26737         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26738         eval $cmd
26739         cmd="exec $fd<&-"
26740         trap "eval $cmd" EXIT
26741         cd $tdir || error "cd $tdir fails"
26742         rmdir  ../$tdir || error "rmdir $tdir fails"
26743         mkdir local_dir && error "create dir succeeds"
26744         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26745         eval $cmd
26746         return 0
26747 }
26748 run_test 300q "create remote directory under orphan directory"
26749
26750 test_300r() {
26751         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26752                 skip "Need MDS version at least 2.7.55" && return
26753         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26754
26755         mkdir $DIR/$tdir
26756
26757         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26758                 error "set striped dir error"
26759
26760         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26761                 error "getstripeddir fails"
26762
26763         local stripe_count
26764         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26765                       awk '/lmv_stripe_count:/ { print $2 }')
26766
26767         [ $MDSCOUNT -ne $stripe_count ] &&
26768                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26769
26770         rm -rf $DIR/$tdir/striped_dir ||
26771                 error "unlink striped dir fails"
26772 }
26773 run_test 300r "test -1 striped directory"
26774
26775 test_300s_helper() {
26776         local count=$1
26777
26778         local stripe_dir=$DIR/$tdir/striped_dir.$count
26779
26780         $LFS mkdir -c $count $stripe_dir ||
26781                 error "lfs mkdir -c error"
26782
26783         $LFS getdirstripe $stripe_dir ||
26784                 error "lfs getdirstripe fails"
26785
26786         local stripe_count
26787         stripe_count=$($LFS getdirstripe $stripe_dir |
26788                       awk '/lmv_stripe_count:/ { print $2 }')
26789
26790         [ $count -ne $stripe_count ] &&
26791                 error_noexit "bad stripe count $stripe_count expected $count"
26792
26793         local dupe_stripes
26794         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26795                 awk '/0x/ {count[$1] += 1}; END {
26796                         for (idx in count) {
26797                                 if (count[idx]>1) {
26798                                         print "index " idx " count " count[idx]
26799                                 }
26800                         }
26801                 }')
26802
26803         if [[ -n "$dupe_stripes" ]] ; then
26804                 lfs getdirstripe $stripe_dir
26805                 error_noexit "Dupe MDT above: $dupe_stripes "
26806         fi
26807
26808         rm -rf $stripe_dir ||
26809                 error_noexit "unlink $stripe_dir fails"
26810 }
26811
26812 test_300s() {
26813         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26814                 skip "Need MDS version at least 2.7.55" && return
26815         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26816
26817         mkdir $DIR/$tdir
26818         for count in $(seq 2 $MDSCOUNT); do
26819                 test_300s_helper $count
26820         done
26821 }
26822 run_test 300s "test lfs mkdir -c without -i"
26823
26824 test_300t() {
26825         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26826                 skip "need MDS 2.14.55 or later"
26827         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26828
26829         local testdir="$DIR/$tdir/striped_dir"
26830         local dir1=$testdir/dir1
26831         local dir2=$testdir/dir2
26832
26833         mkdir -p $testdir
26834
26835         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26836                 error "failed to set default stripe count for $testdir"
26837
26838         mkdir $dir1
26839         local stripe_count=$($LFS getdirstripe -c $dir1)
26840
26841         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26842
26843         local max_count=$((MDSCOUNT - 1))
26844         local mdts=$(comma_list $(mdts_nodes))
26845
26846         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26847         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26848
26849         mkdir $dir2
26850         stripe_count=$($LFS getdirstripe -c $dir2)
26851
26852         (( $stripe_count == $max_count )) || error "wrong stripe count"
26853 }
26854 run_test 300t "test max_mdt_stripecount"
26855
26856 MDT_OVSTRP_VER="2.15.60"
26857 # 300u family tests MDT overstriping
26858 test_300ua() {
26859         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26860
26861         local setcount=$((MDSCOUNT * 2))
26862
26863         local expected_count
26864
26865         mkdir $DIR/$tdir
26866         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26867                 error "(0) failed basic overstriped dir creation test"
26868         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26869
26870         # This does a basic interop test - if the MDS does not support mdt
26871         # overstriping, we should get stripes == number of MDTs
26872         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26873                 expected_count=$MDSCOUNT
26874         else
26875                 expected_count=$setcount
26876         fi
26877         (( getstripe_count == expected_count )) ||
26878                 error "(1) incorrect stripe count for simple overstriped dir"
26879
26880         rm -rf $DIR/$tdir/${tdir}.0 ||
26881                 error "(2) unable to rm overstriped dir"
26882
26883         # Tests after this require overstriping support
26884         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26885                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26886
26887         test_striped_dir 0 $setcount true ||
26888                 error "(3)failed on overstriped dir"
26889         test_striped_dir 1 $setcount true ||
26890                 error "(4)failed on overstriped dir"
26891
26892         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26893
26894         test_striped_dir 0 $setcount true ||
26895                 error "(5)failed on overstriped dir"
26896 }
26897 run_test 300ua "basic overstriped dir sanity test"
26898
26899 test_300ub() {
26900         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26901                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26902         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26903
26904         mkdir $DIR/$tdir
26905
26906         echo "Testing invalid stripe count, failure expected"
26907         local setcount=$((MDSCOUNT * 2))
26908
26909         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26910         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26911
26912         (( getstripe_count <= MDSCOUNT )) ||
26913                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26914
26915         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26916         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26917         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26918
26919         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26920
26921         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26922         (( getstripe_count == maxcount )) ||
26923                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26924
26925         # Test specific striping with -i
26926         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26927
26928         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26929         (( getstripe_count == 4 )) ||
26930                 error "(2)stripe_count is $getstripe_count, expect 4"
26931
26932         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26933                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26934
26935         [[ -n "$nonzeroindices" ]] ||
26936                 error "(3) stripes indices not all 0: $nonzeroindices"
26937
26938         # Test specific striping with too many stripes on one MDT
26939         echo "Testing invalid striping, failure expected"
26940         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26941         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26942         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26943                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26944         echo "stripes on MDT0: $getstripe_count"
26945         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26946                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26947
26948         setcount=$((MDSCOUNT * 2))
26949         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26950                 error "(5) can't setdirstripe with manually set hash function"
26951
26952         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26953         (( getstripe_count == setcount )) ||
26954                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26955
26956         setcount=$((MDSCOUNT * 2))
26957         mkdir $DIR/${tdir}.5
26958         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26959                 error "(7) can't setdirstripe with manually set hash function"
26960         mkdir $DIR/${tdir}.5/${tdir}.6
26961
26962         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26963         (( getstripe_count == setcount )) ||
26964                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26965 }
26966 run_test 300ub "test MDT overstriping interface & limits"
26967
26968 test_300uc() {
26969         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26970                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26971         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26972
26973         mkdir $DIR/$tdir
26974
26975         local setcount=$((MDSCOUNT * 2))
26976
26977         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26978
26979         mkdir $DIR/$tdir/${tdir}.1
26980
26981         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26982
26983         (( getstripe_count == setcount )) ||
26984                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26985
26986         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26987
26988         local getstripe_count=$($LFS getdirstripe -c \
26989                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26990
26991         (( getstripe_count == setcount )) ||
26992                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26993 }
26994 run_test 300uc "test MDT overstriping as default & inheritance"
26995
26996 test_300ud() {
26997         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26998                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26999         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27000
27001         local mdts=$(comma_list $(mdts_nodes))
27002         local timeout=100
27003
27004         local restripe_status
27005         local delta
27006         local i
27007
27008         [[ $mds1_FSTYPE == zfs ]] && timeout=300
27009
27010         # in case "crush" hash type is not set
27011         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
27012
27013         restripe_status=$(do_facet mds1 $LCTL get_param -n \
27014                            mdt.*MDT0000.enable_dir_restripe)
27015         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
27016         stack_trap "do_nodes $mdts $LCTL set_param \
27017                     mdt.*.enable_dir_restripe=$restripe_status"
27018
27019         mkdir $DIR/$tdir
27020         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
27021                 error "create files under remote dir failed $i"
27022         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
27023                 error "create dirs under remote dir failed $i"
27024
27025         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27026
27027         (( setcount < 13 )) || setcount=12
27028         for i in $(seq 2 $setcount); do
27029                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
27030                 $LFS setdirstripe -C $i $DIR/$tdir ||
27031                         error "split -C $i $tdir failed"
27032                 wait_update $HOSTNAME \
27033                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
27034                         error "dir split not finished"
27035                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
27036                         awk '/migrate/ {sum += $2} END { print sum }')
27037                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
27038                 # delta is around total_files/stripe_count, deviation 3%
27039                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
27040                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
27041         done
27042 }
27043 run_test 300ud "dir split"
27044
27045 test_300ue() {
27046         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
27047                 skip "skipped for MDS < $MDT_OVSTRP_VER"
27048         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27049
27050         local mdts=$(comma_list $(mdts_nodes))
27051         local timeout=100
27052
27053         local restripe_status
27054         local delta
27055         local c
27056
27057         [[ $mds1_FSTYPE == zfs ]] && timeout=300
27058
27059         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
27060
27061         restripe_status=$(do_facet mds1 $LCTL get_param -n \
27062                            mdt.*MDT0000.enable_dir_restripe)
27063         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
27064         stack_trap "do_nodes $mdts $LCTL set_param \
27065                     mdt.*.enable_dir_restripe=$restripe_status"
27066
27067         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27068
27069         (( setcount < 13 )) || setcount=12
27070         test_mkdir -C $setcount -H crush $DIR/$tdir
27071         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
27072                 error "create files under remote dir failed"
27073         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
27074                 error "create dirs under remote dir failed"
27075
27076         for c in $(seq $((setcount - 1)) -1 1); do
27077                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
27078                 $LFS setdirstripe -C $c $DIR/$tdir ||
27079                         error "split -C $c $tdir failed"
27080                 wait_update $HOSTNAME \
27081                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
27082                         error "dir merge not finished"
27083                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
27084                         awk '/migrate/ {sum += $2} END { print sum }')
27085                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
27086                 # delta is around total_files/stripe_count, deviation 3%
27087                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
27088                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
27089         done
27090 }
27091 run_test 300ue "dir merge"
27092
27093 test_300uf() {
27094         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
27095                 skip "skipped for MDS < $MDT_OVSTRP_VER"
27096         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27097
27098         # maximum amount of local locks:
27099         # parent striped dir - 2 locks
27100         # new stripe in parent to migrate to - 1 lock
27101         # source and target - 2 locks
27102         # Total 5 locks for regular file
27103         #
27104         # NB: Overstriping should add several extra local locks
27105         # FIXME: Remove this once understood
27106         #lctl set_param *debug=-1 debug_mb=10000
27107         lctl clear
27108         lctl mark "touch/create"
27109         mkdir -p $DIR/$tdir
27110         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27111         local setcount=$((MDSCOUNT * 5))
27112
27113         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
27114         touch $DIR/$tdir/dir1/eee
27115
27116         lctl mark "hardlinks"
27117         # create 4 hardlink for 4 more locks
27118         # Total: 9 locks > RS_MAX_LOCKS (8)
27119         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
27120         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
27121         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
27122         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
27123         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
27124         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
27125         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
27126         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
27127
27128         lctl mark "cancel lru"
27129         cancel_lru_locks mdc
27130
27131         lctl mark "migrate"
27132         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
27133                 error "migrate dir fails"
27134
27135         rm -rf $DIR/$tdir || error "rm dir failed after migration"
27136 }
27137 run_test 300uf "migrate with too many local locks"
27138
27139 test_300ug() {
27140         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
27141                 skip "skipped for MDS < $MDT_OVSTRP_VER"
27142         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
27143
27144         mkdir -p $DIR/$tdir
27145         local migrate_dir=$DIR/$tdir/migrate_dir
27146         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
27147         local setcount2=$((setcount - 2))
27148
27149         $LFS setdirstripe -c 2 $migrate_dir ||
27150                 error "(0) failed to create striped directory"
27151
27152         $LFS migrate -m 0 -C $setcount $migrate_dir ||
27153                 error "(1)failed to migrate to overstriped directory"
27154         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27155
27156         (( getstripe_count == setcount )) ||
27157                 error "(2)stripe_count is $getstripe_count, expect $setcount"
27158         touch $DIR/$tdir/migrate_dir/$tfile ||
27159                 error "(3)failed to create file in overstriped directory"
27160         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
27161                 error "(4)failed to migrate overstriped directory"
27162         # Check stripe count after migration
27163         $LFS getdirstripe $migrate_dir
27164         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
27165         (( getstripe_count == setcount2 )) ||
27166                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
27167
27168         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
27169 }
27170 run_test 300ug "migrate overstriped dirs"
27171
27172 prepare_remote_file() {
27173         mkdir $DIR/$tdir/src_dir ||
27174                 error "create remote source failed"
27175
27176         cp /etc/hosts $DIR/$tdir/src_dir/a ||
27177                  error "cp to remote source failed"
27178         touch $DIR/$tdir/src_dir/a
27179
27180         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
27181                 error "create remote target dir failed"
27182
27183         touch $DIR/$tdir/tgt_dir/b
27184
27185         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
27186                 error "rename dir cross MDT failed!"
27187
27188         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
27189                 error "src_child still exists after rename"
27190
27191         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
27192                 error "missing file(a) after rename"
27193
27194         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
27195                 error "diff after rename"
27196 }
27197
27198 test_310a() {
27199         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27201
27202         local remote_file=$DIR/$tdir/tgt_dir/b
27203
27204         mkdir -p $DIR/$tdir
27205
27206         prepare_remote_file || error "prepare remote file failed"
27207
27208         #open-unlink file
27209         $OPENUNLINK $remote_file $remote_file ||
27210                 error "openunlink $remote_file failed"
27211         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27212 }
27213 run_test 310a "open unlink remote file"
27214
27215 test_310b() {
27216         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27218
27219         local remote_file=$DIR/$tdir/tgt_dir/b
27220
27221         mkdir -p $DIR/$tdir
27222
27223         prepare_remote_file || error "prepare remote file failed"
27224
27225         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27226         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27227         $CHECKSTAT -t file $remote_file || error "check file failed"
27228 }
27229 run_test 310b "unlink remote file with multiple links while open"
27230
27231 test_310c() {
27232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27233         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27234
27235         local remote_file=$DIR/$tdir/tgt_dir/b
27236
27237         mkdir -p $DIR/$tdir
27238
27239         prepare_remote_file || error "prepare remote file failed"
27240
27241         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27242         multiop_bg_pause $remote_file O_uc ||
27243                         error "mulitop failed for remote file"
27244         MULTIPID=$!
27245         $MULTIOP $DIR/$tfile Ouc
27246         kill -USR1 $MULTIPID
27247         wait $MULTIPID
27248 }
27249 run_test 310c "open-unlink remote file with multiple links"
27250
27251 #LU-4825
27252 test_311() {
27253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27254         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27255         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27256                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27257         remote_mds_nodsh && skip "remote MDS with nodsh"
27258
27259         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27260         local mdts=$(comma_list $(mdts_nodes))
27261
27262         mkdir -p $DIR/$tdir
27263         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27264         createmany -o $DIR/$tdir/$tfile. 1000
27265
27266         # statfs data is not real time, let's just calculate it
27267         old_iused=$((old_iused + 1000))
27268
27269         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27270                         osp.*OST0000*MDT0000.create_count")
27271         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27272                                 osp.*OST0000*MDT0000.max_create_count")
27273         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27274
27275         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27276         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27277         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27278
27279         unlinkmany $DIR/$tdir/$tfile. 1000
27280
27281         do_nodes $mdts "$LCTL set_param -n \
27282                         osp.*OST0000*.max_create_count=$max_count"
27283         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27284                 do_nodes $mdts "$LCTL set_param -n \
27285                                 osp.*OST0000*.create_count=$count"
27286         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27287                         grep "=0" && error "create_count is zero"
27288
27289         local new_iused
27290         for i in $(seq 120); do
27291                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27292                 # system may be too busy to destroy all objs in time, use
27293                 # a somewhat small value to not fail autotest
27294                 [ $((old_iused - new_iused)) -gt 400 ] && break
27295                 sleep 1
27296         done
27297
27298         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27299         [ $((old_iused - new_iused)) -gt 400 ] ||
27300                 error "objs not destroyed after unlink"
27301 }
27302 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27303
27304 zfs_get_objid()
27305 {
27306         local ost=$1
27307         local tf=$2
27308         local fid=($($LFS getstripe $tf | grep 0x))
27309         local seq=${fid[3]#0x}
27310         local objid=${fid[1]}
27311
27312         local vdevdir=$(dirname $(facet_vdevice $ost))
27313         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27314         local zfs_zapid=$(do_facet $ost $cmd |
27315                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27316                           awk '/Object/{getline; print $1}')
27317         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27318                           awk "/$objid = /"'{printf $3}')
27319
27320         echo $zfs_objid
27321 }
27322
27323 zfs_object_blksz() {
27324         local ost=$1
27325         local objid=$2
27326
27327         local vdevdir=$(dirname $(facet_vdevice $ost))
27328         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27329         local blksz=$(do_facet $ost $cmd $objid |
27330                       awk '/dblk/{getline; printf $4}')
27331
27332         case "${blksz: -1}" in
27333                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27334                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27335                 *) ;;
27336         esac
27337
27338         echo $blksz
27339 }
27340
27341 test_312() { # LU-4856
27342         remote_ost_nodsh && skip "remote OST with nodsh"
27343         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27344
27345         local max_blksz=$(do_facet ost1 \
27346                           $ZFS get -p recordsize $(facet_device ost1) |
27347                           awk '!/VALUE/{print $3}')
27348         local tf=$DIR/$tfile
27349
27350         $LFS setstripe -c1 $tf
27351         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27352
27353         # Get ZFS object id
27354         local zfs_objid=$(zfs_get_objid $facet $tf)
27355         # block size change by sequential overwrite
27356         local bs
27357
27358         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27359                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27360
27361                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27362                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27363         done
27364         rm -f $tf
27365
27366         $LFS setstripe -c1 $tf
27367         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27368
27369         # block size change by sequential append write
27370         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27371         zfs_objid=$(zfs_get_objid $facet $tf)
27372         local count
27373
27374         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27375                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27376                         oflag=sync conv=notrunc
27377
27378                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27379                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27380                         error "blksz error, actual $blksz, " \
27381                                 "expected: 2 * $count * $PAGE_SIZE"
27382         done
27383         rm -f $tf
27384
27385         # random write
27386         $LFS setstripe -c1 $tf
27387         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27388         zfs_objid=$(zfs_get_objid $facet $tf)
27389
27390         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27391         blksz=$(zfs_object_blksz $facet $zfs_objid)
27392         (( blksz == PAGE_SIZE )) ||
27393                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27394
27395         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27396         blksz=$(zfs_object_blksz $facet $zfs_objid)
27397         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27398
27399         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27400         blksz=$(zfs_object_blksz $facet $zfs_objid)
27401         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27402 }
27403 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27404
27405 test_313() {
27406         remote_ost_nodsh && skip "remote OST with nodsh"
27407
27408         local file=$DIR/$tfile
27409
27410         rm -f $file
27411         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27412
27413         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27414         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27415         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27416                 error "write should failed"
27417         do_facet ost1 "$LCTL set_param fail_loc=0"
27418         rm -f $file
27419 }
27420 run_test 313 "io should fail after last_rcvd update fail"
27421
27422 test_314() {
27423         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27424
27425         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27426         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27427         rm -f $DIR/$tfile
27428         wait_delete_completed
27429         do_facet ost1 "$LCTL set_param fail_loc=0"
27430 }
27431 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27432
27433 test_315() { # LU-618
27434         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27435
27436         local file=$DIR/$tfile
27437         rm -f $file
27438
27439         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27440                 error "multiop file write failed"
27441         $MULTIOP $file oO_RDONLY:r4063232_c &
27442         PID=$!
27443
27444         sleep 2
27445
27446         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27447         kill -USR1 $PID
27448
27449         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27450         rm -f $file
27451 }
27452 run_test 315 "read should be accounted"
27453
27454 test_316() {
27455         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27456         large_xattr_enabled || skip "ea_inode feature disabled"
27457
27458         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27459         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27460         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27461         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27462
27463         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27464 }
27465 run_test 316 "lfs migrate of file with large_xattr enabled"
27466
27467 test_317() {
27468         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27469                 skip "Need MDS version at least 2.11.53"
27470         if [ "$ost1_FSTYPE" == "zfs" ]; then
27471                 skip "LU-10370: no implementation for ZFS"
27472         fi
27473
27474         local trunc_sz
27475         local grant_blk_size
27476
27477         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27478                         awk '/grant_block_size:/ { print $2; exit; }')
27479         #
27480         # Create File of size 5M. Truncate it to below size's and verify
27481         # blocks count.
27482         #
27483         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27484                 error "Create file $DIR/$tfile failed"
27485         stack_trap "rm -f $DIR/$tfile" EXIT
27486
27487         for trunc_sz in 2097152 4097 4000 509 0; do
27488                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27489                         error "truncate $tfile to $trunc_sz failed"
27490                 local sz=$(stat --format=%s $DIR/$tfile)
27491                 local blk=$(stat --format=%b $DIR/$tfile)
27492                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27493                                      grant_blk_size) * 8))
27494
27495                 if [[ $blk -ne $trunc_blk ]]; then
27496                         $(which stat) $DIR/$tfile
27497                         error "Expected Block $trunc_blk got $blk for $tfile"
27498                 fi
27499
27500                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27501                         error "Expected Size $trunc_sz got $sz for $tfile"
27502         done
27503
27504         #
27505         # sparse file test
27506         # Create file with a hole and write actual 65536 bytes which aligned
27507         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27508         #
27509         local bs=65536
27510         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27511                 error "Create file : $DIR/$tfile"
27512
27513         #
27514         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27515         # blocks. The block count must drop to 8.
27516         #
27517         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27518                 ((bs - grant_blk_size) + 1)))
27519         $TRUNCATE $DIR/$tfile $trunc_sz ||
27520                 error "truncate $tfile to $trunc_sz failed"
27521
27522         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27523         sz=$(stat --format=%s $DIR/$tfile)
27524         blk=$(stat --format=%b $DIR/$tfile)
27525
27526         if [[ $blk -ne $trunc_bsz ]]; then
27527                 $(which stat) $DIR/$tfile
27528                 error "Expected Block $trunc_bsz got $blk for $tfile"
27529         fi
27530
27531         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27532                 error "Expected Size $trunc_sz got $sz for $tfile"
27533 }
27534 run_test 317 "Verify blocks get correctly update after truncate"
27535
27536 test_318() {
27537         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27538         local old_max_active=$($LCTL get_param -n \
27539                             ${llite_name}.max_read_ahead_async_active \
27540                             2>/dev/null)
27541
27542         $LCTL set_param llite.*.max_read_ahead_async_active=256
27543         local max_active=$($LCTL get_param -n \
27544                            ${llite_name}.max_read_ahead_async_active \
27545                            2>/dev/null)
27546         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27547
27548         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27549                 error "set max_read_ahead_async_active should succeed"
27550
27551         $LCTL set_param llite.*.max_read_ahead_async_active=512
27552         max_active=$($LCTL get_param -n \
27553                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27554         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27555
27556         # restore @max_active
27557         [ $old_max_active -ne 0 ] && $LCTL set_param \
27558                 llite.*.max_read_ahead_async_active=$old_max_active
27559
27560         local old_threshold=$($LCTL get_param -n \
27561                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27562         local max_per_file_mb=$($LCTL get_param -n \
27563                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27564
27565         local invalid=$(($max_per_file_mb + 1))
27566         $LCTL set_param \
27567                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27568                         && error "set $invalid should fail"
27569
27570         local valid=$(($invalid - 1))
27571         $LCTL set_param \
27572                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27573                         error "set $valid should succeed"
27574         local threshold=$($LCTL get_param -n \
27575                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27576         [ $threshold -eq $valid ] || error \
27577                 "expect threshold $valid got $threshold"
27578         $LCTL set_param \
27579                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27580 }
27581 run_test 318 "Verify async readahead tunables"
27582
27583 test_319() {
27584         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27585
27586         local before=$(date +%s)
27587         local evict
27588         local mdir=$DIR/$tdir
27589         local file=$mdir/xxx
27590
27591         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27592         touch $file
27593
27594 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27595         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27596         $LFS migrate -m1 $mdir &
27597
27598         sleep 1
27599         dd if=$file of=/dev/null
27600         wait
27601         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27602           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27603
27604         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27605 }
27606 run_test 319 "lost lease lock on migrate error"
27607
27608 test_350() {
27609         local mdts=$(comma_list $(mdts_nodes))
27610
27611         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27612         stack_trap "rm -r $DIR/$tdir"
27613
27614         #force 1/100 of replies to take "NID mismatch" codepath
27615         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27616         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27617
27618         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27619         stack_trap "killall -9 ls || killall -9 ls"
27620
27621         cp -a /etc $DIR/$tdir || error "cp failed"
27622 }
27623 run_test 350 "force NID mismatch path to be exercised"
27624
27625 test_360() {
27626         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27627                 skip "Need OST version at least 2.15.58.96"
27628         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27629
27630         check_set_fallocate_or_skip
27631         local param="osd-ldiskfs.delayed_unlink_mb"
27632         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27633
27634         do_facet ost1 "$LCTL set_param $param=1MiB"
27635         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27636
27637         mkdir $DIR/$tdir/
27638         do_facet ost1 $LCTL set_param debug=+inode
27639         do_facet ost1 $LCTL clear
27640         local files=100
27641
27642         for ((i = 0; i < $files; i++)); do
27643                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27644                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27645         done
27646         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27647
27648         for ((i = 0; i < $files; i++)); do
27649                 unlink $DIR/$tdir/$tfile.$i ||
27650                         error "unlink $DIR/$tdir/$tfile.$i failed"
27651         done
27652
27653         local count=0
27654         local loop
27655
27656         for (( loop = 0; loop < 30 && count < min; loop++)); do
27657                 sleep 1
27658                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27659                 echo "Count[$loop]: $count"
27660         done
27661         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27662 }
27663 run_test 360 "ldiskfs unlink in a separate thread"
27664
27665 test_398a() { # LU-4198
27666         local ost1_imp=$(get_osc_import_name client ost1)
27667         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27668                          cut -d'.' -f2)
27669
27670         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27671         stack_trap "rm -f $DIR/$tfile"
27672         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27673
27674         # request a new lock on client
27675         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27676
27677         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27678         local lock_count=$($LCTL get_param -n \
27679                            ldlm.namespaces.$imp_name.lru_size)
27680         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27681
27682         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27683
27684         # no lock cached, should use lockless DIO and not enqueue new lock
27685         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27686         lock_count=$($LCTL get_param -n \
27687                      ldlm.namespaces.$imp_name.lru_size)
27688         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27689
27690         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27691
27692         # no lock cached, should use locked DIO append
27693         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27694                 conv=notrunc || error "DIO append failed"
27695         lock_count=$($LCTL get_param -n \
27696                      ldlm.namespaces.$imp_name.lru_size)
27697         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27698 }
27699 run_test 398a "direct IO should cancel lock otherwise lockless"
27700
27701 test_398b() { # LU-4198
27702         local before=$(date +%s)
27703         local njobs=4
27704         local size=48
27705
27706         which fio || skip_env "no fio installed"
27707         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27708         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27709
27710         # Single page, multiple pages, stripe size, 4*stripe size
27711         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27712                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27713                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27714                         --numjobs=$njobs --fallocate=none \
27715                         --iodepth=16 --allow_file_create=0 \
27716                         --size=$((size/njobs))M \
27717                         --filename=$DIR/$tfile &
27718                 bg_pid=$!
27719
27720                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27721                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27722                         --numjobs=$njobs --fallocate=none \
27723                         --iodepth=16 --allow_file_create=0 \
27724                         --size=$((size/njobs))M \
27725                         --filename=$DIR/$tfile || true
27726                 wait $bg_pid
27727         done
27728
27729         evict=$(do_facet client $LCTL get_param \
27730                 osc.$FSNAME-OST*-osc-*/state |
27731             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27732
27733         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27734                 (do_facet client $LCTL get_param \
27735                         osc.$FSNAME-OST*-osc-*/state;
27736                     error "eviction happened: $evict before:$before")
27737
27738         rm -f $DIR/$tfile
27739 }
27740 run_test 398b "DIO and buffer IO race"
27741
27742 test_398c() { # LU-4198
27743         local ost1_imp=$(get_osc_import_name client ost1)
27744         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27745                          cut -d'.' -f2)
27746
27747         which fio || skip_env "no fio installed"
27748
27749         saved_debug=$($LCTL get_param -n debug)
27750         $LCTL set_param debug=0
27751
27752         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27753         ((size /= 1024)) # by megabytes
27754         ((size /= 2)) # write half of the OST at most
27755         [ $size -gt 40 ] && size=40 #reduce test time anyway
27756
27757         $LFS setstripe -c 1 $DIR/$tfile
27758
27759         # it seems like ldiskfs reserves more space than necessary if the
27760         # writing blocks are not mapped, so it extends the file firstly
27761         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27762         cancel_lru_locks osc
27763
27764         # clear and verify rpc_stats later
27765         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27766
27767         local njobs=4
27768         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27769         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27770                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27771                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27772                 --filename=$DIR/$tfile
27773         [ $? -eq 0 ] || error "fio write error"
27774
27775         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27776                 error "Locks were requested while doing AIO"
27777
27778         # get the percentage of 1-page I/O
27779         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27780                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27781                 awk '{print $7}')
27782         (( $pct <= 50 )) || {
27783                 $LCTL get_param osc.${imp_name}.rpc_stats
27784                 error "$pct% of I/O are 1-page"
27785         }
27786
27787         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27788         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27789                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27790                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27791                 --filename=$DIR/$tfile
27792         [ $? -eq 0 ] || error "fio mixed read write error"
27793
27794         echo "AIO with large block size ${size}M"
27795         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27796                 --numjobs=1 --fallocate=none --ioengine=libaio \
27797                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27798                 --filename=$DIR/$tfile
27799         [ $? -eq 0 ] || error "fio large block size failed"
27800
27801         rm -f $DIR/$tfile
27802         $LCTL set_param debug="$saved_debug"
27803 }
27804 run_test 398c "run fio to test AIO"
27805
27806 test_398d() { #  LU-13846
27807         which aiocp || skip_env "no aiocp installed"
27808         local aio_file=$DIR/$tfile.aio
27809
27810         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27811
27812         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27813         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27814         stack_trap "rm -f $DIR/$tfile $aio_file"
27815
27816         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27817
27818         # test memory unaligned aio
27819         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27820                 error "unaligned aio failed"
27821         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27822
27823         rm -f $DIR/$tfile $aio_file
27824 }
27825 run_test 398d "run aiocp to verify block size > stripe size"
27826
27827 test_398e() {
27828         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27829         touch $DIR/$tfile.new
27830         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27831 }
27832 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27833
27834 test_398f() { #  LU-14687
27835         which aiocp || skip_env "no aiocp installed"
27836         local aio_file=$DIR/$tfile.aio
27837
27838         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27839
27840         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27841         stack_trap "rm -f $DIR/$tfile $aio_file"
27842
27843         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27844         $LCTL set_param fail_loc=0x1418
27845         # make sure we don't crash and fail properly
27846         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27847                 error "aio with page allocation failure succeeded"
27848         $LCTL set_param fail_loc=0
27849         diff $DIR/$tfile $aio_file
27850         [[ $? != 0 ]] || error "no diff after failed aiocp"
27851 }
27852 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27853
27854 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27855 # stripe and i/o size must be > stripe size
27856 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27857 # single RPC in flight.  This test shows async DIO submission is working by
27858 # showing multiple RPCs in flight.
27859 test_398g() { #  LU-13798
27860         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27861
27862         # We need to do some i/o first to acquire enough grant to put our RPCs
27863         # in flight; otherwise a new connection may not have enough grant
27864         # available
27865         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27866                 error "parallel dio failed"
27867         stack_trap "rm -f $DIR/$tfile"
27868
27869         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27870         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27871         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27872         stack_trap "$LCTL set_param -n $pages_per_rpc"
27873
27874         # Recreate file so it's empty
27875         rm -f $DIR/$tfile
27876         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27877         #Pause rpc completion to guarantee we see multiple rpcs in flight
27878         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27879         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27880         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27881
27882         # Clear rpc stats
27883         $LCTL set_param osc.*.rpc_stats=c
27884
27885         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27886                 error "parallel dio failed"
27887         stack_trap "rm -f $DIR/$tfile"
27888
27889         $LCTL get_param osc.*-OST0000-*.rpc_stats
27890         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27891                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27892                 grep "8:" | awk '{print $8}')
27893         # We look at the "8 rpcs in flight" field, and verify A) it is present
27894         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27895         # as expected for an 8M DIO to a file with 1M stripes.
27896         # NB: There is occasionally a mystery extra write RPC to a different
27897         # file.  I can't identify why that's happening, so we set up a margin
27898         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27899         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27900
27901         # Verify turning off parallel dio works as expected
27902         # Clear rpc stats
27903         $LCTL set_param osc.*.rpc_stats=c
27904         $LCTL set_param llite.*.parallel_dio=0
27905         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27906
27907         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27908                 error "dio with parallel dio disabled failed"
27909
27910         # Ideally, we would see only one RPC in flight here, but there is an
27911         # unavoidable race between i/o completion and RPC in flight counting,
27912         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27913         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27914         # So instead we just verify it's always < 8.
27915         $LCTL get_param osc.*-OST0000-*.rpc_stats
27916         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27917                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27918                 grep '^$' -B1 | grep . | awk '{print $1}')
27919         [ $ret != "8:" ] ||
27920                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27921 }
27922 run_test 398g "verify parallel dio async RPC submission"
27923
27924 test_398h() { #  LU-13798
27925         local dio_file=$DIR/$tfile.dio
27926
27927         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27928
27929         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27930         stack_trap "rm -f $DIR/$tfile $dio_file"
27931
27932         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27933                 error "parallel dio failed"
27934         diff $DIR/$tfile $dio_file
27935         [[ $? == 0 ]] || error "file diff after aiocp"
27936 }
27937 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27938
27939 test_398i() { #  LU-13798
27940         local dio_file=$DIR/$tfile.dio
27941
27942         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27943
27944         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27945         stack_trap "rm -f $DIR/$tfile $dio_file"
27946
27947         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27948         $LCTL set_param fail_loc=0x1418
27949         # make sure we don't crash and fail properly
27950         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27951                 error "parallel dio page allocation failure succeeded"
27952         diff $DIR/$tfile $dio_file
27953         [[ $? != 0 ]] || error "no diff after failed aiocp"
27954 }
27955 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27956
27957 test_398j() { #  LU-13798
27958         # Stripe size > RPC size but less than i/o size tests split across
27959         # stripes and RPCs for individual i/o op
27960         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27961
27962         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27963         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27964         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27965         stack_trap "$LCTL set_param -n $pages_per_rpc"
27966
27967         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27968                 error "parallel dio write failed"
27969         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27970
27971         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27972                 error "parallel dio read failed"
27973         diff $DIR/$tfile $DIR/$tfile.2
27974         [[ $? == 0 ]] || error "file diff after parallel dio read"
27975 }
27976 run_test 398j "test parallel dio where stripe size > rpc_size"
27977
27978 test_398k() { #  LU-13798
27979         wait_delete_completed
27980         wait_mds_ost_sync
27981
27982         # 4 stripe file; we will cause out of space on OST0
27983         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27984
27985         # Fill OST0 (if it's not too large)
27986         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27987                    head -n1)
27988         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27989                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27990         fi
27991         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27992         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27993                 error "dd should fill OST0"
27994         stack_trap "rm -f $DIR/$tfile.1"
27995
27996         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27997         err=$?
27998
27999         ls -la $DIR/$tfile
28000         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
28001                 error "file is not 0 bytes in size"
28002
28003         # dd above should not succeed, but don't error until here so we can
28004         # get debug info above
28005         [[ $err != 0 ]] ||
28006                 error "parallel dio write with enospc succeeded"
28007         stack_trap "rm -f $DIR/$tfile"
28008 }
28009 run_test 398k "test enospc on first stripe"
28010
28011 test_398l() { #  LU-13798
28012         wait_delete_completed
28013         wait_mds_ost_sync
28014
28015         # 4 stripe file; we will cause out of space on OST0
28016         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
28017         # happens on the second i/o chunk we issue
28018         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
28019
28020         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
28021         stack_trap "rm -f $DIR/$tfile"
28022
28023         # Fill OST0 (if it's not too large)
28024         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
28025                    head -n1)
28026         if [[ $ORIGFREE -gt $MAXFREE ]]; then
28027                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
28028         fi
28029         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
28030         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
28031                 error "dd should fill OST0"
28032         stack_trap "rm -f $DIR/$tfile.1"
28033
28034         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
28035         err=$?
28036         stack_trap "rm -f $DIR/$tfile.2"
28037
28038         # Check that short write completed as expected
28039         ls -la $DIR/$tfile.2
28040         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
28041                 error "file is not 1M in size"
28042
28043         # dd above should not succeed, but don't error until here so we can
28044         # get debug info above
28045         [[ $err != 0 ]] ||
28046                 error "parallel dio write with enospc succeeded"
28047
28048         # Truncate source file to same length as output file and diff them
28049         $TRUNCATE $DIR/$tfile 1048576
28050         diff $DIR/$tfile $DIR/$tfile.2
28051         [[ $? == 0 ]] || error "data incorrect after short write"
28052 }
28053 run_test 398l "test enospc on intermediate stripe/RPC"
28054
28055 test_398m() { #  LU-13798
28056         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
28057
28058         # Set up failure on OST0, the first stripe:
28059         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
28060         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
28061         # OST0 is on ost1, OST1 is on ost2.
28062         # So this fail_val specifies OST0
28063         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
28064         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
28065
28066         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
28067                 error "parallel dio write with failure on first stripe succeeded"
28068         stack_trap "rm -f $DIR/$tfile"
28069         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
28070
28071         # Place data in file for read
28072         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
28073                 error "parallel dio write failed"
28074
28075         # Fail read on OST0, first stripe
28076         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28077         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
28078         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
28079                 error "parallel dio read with error on first stripe succeeded"
28080         rm -f $DIR/$tfile.2
28081         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
28082
28083         # Switch to testing on OST1, second stripe
28084         # Clear file contents, maintain striping
28085         echo > $DIR/$tfile
28086         # Set up failure on OST1, second stripe:
28087         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
28088         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
28089
28090         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
28091                 error "parallel dio write with failure on second stripe succeeded"
28092         stack_trap "rm -f $DIR/$tfile"
28093         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
28094
28095         # Place data in file for read
28096         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
28097                 error "parallel dio write failed"
28098
28099         # Fail read on OST1, second stripe
28100         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28101         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
28102         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
28103                 error "parallel dio read with error on second stripe succeeded"
28104         rm -f $DIR/$tfile.2
28105         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
28106 }
28107 run_test 398m "test RPC failures with parallel dio"
28108
28109 # Parallel submission of DIO should not cause problems for append, but it's
28110 # important to verify.
28111 test_398n() { #  LU-13798
28112         $LFS setstripe -C 2 -S 1M $DIR/$tfile
28113
28114         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
28115                 error "dd to create source file failed"
28116         stack_trap "rm -f $DIR/$tfile"
28117
28118         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
28119                 error "parallel dio write with failure on second stripe succeeded"
28120         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
28121         diff $DIR/$tfile $DIR/$tfile.1
28122         [[ $? == 0 ]] || error "data incorrect after append"
28123
28124 }
28125 run_test 398n "test append with parallel DIO"
28126
28127 test_398o() {
28128         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
28129 }
28130 run_test 398o "right kms with DIO"
28131
28132 test_398p()
28133 {
28134         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28135         which aiocp || skip_env "no aiocp installed"
28136
28137         local stripe_size=$((1024 * 1024)) #1 MiB
28138         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28139         local file_size=$((25 * stripe_size))
28140
28141         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28142         stack_trap "rm -f $DIR/$tfile*"
28143         # Just a bit bigger than the largest size in the test set below
28144         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28145                 error "buffered i/o to create file failed"
28146
28147         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28148                 $((stripe_size * 4)); do
28149
28150                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28151
28152                 echo "bs: $bs, file_size $file_size"
28153                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
28154                         $DIR/$tfile.1 $DIR/$tfile.2 &
28155                 pid_dio1=$!
28156                 # Buffered I/O with similar but not the same block size
28157                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28158                         conv=notrunc &
28159                 pid_bio2=$!
28160                 wait $pid_dio1
28161                 rc1=$?
28162                 wait $pid_bio2
28163                 rc2=$?
28164                 if (( rc1 != 0 )); then
28165                         error "aio copy 1 w/bsize $bs failed: $rc1"
28166                 fi
28167                 if (( rc2 != 0 )); then
28168                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28169                 fi
28170
28171                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28172                         error "size incorrect"
28173                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
28174                         error "files differ, bsize $bs"
28175                 rm -f $DIR/$tfile.2
28176         done
28177 }
28178 run_test 398p "race aio with buffered i/o"
28179
28180 test_398q()
28181 {
28182         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28183
28184         local stripe_size=$((1024 * 1024)) #1 MiB
28185         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28186         local file_size=$((25 * stripe_size))
28187
28188         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28189         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28190
28191         # Just a bit bigger than the largest size in the test set below
28192         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28193                 error "buffered i/o to create file failed"
28194
28195         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28196                 $((stripe_size * 4)); do
28197
28198                 echo "bs: $bs, file_size $file_size"
28199                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
28200                         conv=notrunc oflag=direct iflag=direct &
28201                 pid_dio1=$!
28202                 # Buffered I/O with similar but not the same block size
28203                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28204                         conv=notrunc &
28205                 pid_bio2=$!
28206                 wait $pid_dio1
28207                 rc1=$?
28208                 wait $pid_bio2
28209                 rc2=$?
28210                 if (( rc1 != 0 )); then
28211                         error "dio copy 1 w/bsize $bs failed: $rc1"
28212                 fi
28213                 if (( rc2 != 0 )); then
28214                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28215                 fi
28216
28217                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28218                         error "size incorrect"
28219                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28220                         error "files differ, bsize $bs"
28221         done
28222
28223         rm -f $DIR/$tfile*
28224 }
28225 run_test 398q "race dio with buffered i/o"
28226
28227 test_398r() {
28228         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28229         echo "hello, world" > $DIR/$tfile
28230
28231         cancel_lru_locks osc
28232
28233 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28234         do_facet ost1 $LCTL set_param fail_loc=0x20f
28235         cat $DIR/$tfile > /dev/null && error "cat should fail"
28236         return 0
28237 }
28238 run_test 398r "i/o error on file read"
28239
28240 test_398s() {
28241         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28242                 skip "remote OST"
28243
28244         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28245                 error "mirror create failed"
28246
28247         echo "hello, world" > $DIR/$tfile
28248         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28249
28250         cancel_lru_locks osc
28251
28252 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28253         do_facet ost1 $LCTL set_param fail_loc=0x20f
28254         cat $DIR/$tfile > /dev/null && error "cat should fail"
28255         return 0
28256 }
28257 run_test 398s "i/o error on mirror file read"
28258
28259 test_fake_rw() {
28260         local read_write=$1
28261         if [ "$read_write" = "write" ]; then
28262                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28263         elif [ "$read_write" = "read" ]; then
28264                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28265         else
28266                 error "argument error"
28267         fi
28268
28269         # turn off debug for performance testing
28270         local saved_debug=$($LCTL get_param -n debug)
28271         $LCTL set_param debug=0
28272
28273         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28274
28275         # get ost1 size - $FSNAME-OST0000
28276         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28277         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28278         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28279
28280         if [ "$read_write" = "read" ]; then
28281                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28282         fi
28283
28284         local start_time=$(date +%s.%N)
28285         $dd_cmd bs=1M count=$blocks oflag=sync ||
28286                 error "real dd $read_write error"
28287         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28288
28289         if [ "$read_write" = "write" ]; then
28290                 rm -f $DIR/$tfile
28291         fi
28292
28293         # define OBD_FAIL_OST_FAKE_RW           0x238
28294         do_facet ost1 $LCTL set_param fail_loc=0x238
28295
28296         local start_time=$(date +%s.%N)
28297         $dd_cmd bs=1M count=$blocks oflag=sync ||
28298                 error "fake dd $read_write error"
28299         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28300
28301         if [ "$read_write" = "write" ]; then
28302                 # verify file size
28303                 cancel_lru_locks osc
28304                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28305                         error "$tfile size not $blocks MB"
28306         fi
28307         do_facet ost1 $LCTL set_param fail_loc=0
28308
28309         echo "fake $read_write $duration_fake vs. normal $read_write" \
28310                 "$duration in seconds"
28311         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28312                 error_not_in_vm "fake write is slower"
28313
28314         $LCTL set_param -n debug="$saved_debug"
28315         rm -f $DIR/$tfile
28316 }
28317 test_399a() { # LU-7655 for OST fake write
28318         remote_ost_nodsh && skip "remote OST with nodsh"
28319
28320         test_fake_rw write
28321 }
28322 run_test 399a "fake write should not be slower than normal write"
28323
28324 test_399b() { # LU-8726 for OST fake read
28325         remote_ost_nodsh && skip "remote OST with nodsh"
28326         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28327                 skip_env "ldiskfs only test"
28328         fi
28329
28330         test_fake_rw read
28331 }
28332 run_test 399b "fake read should not be slower than normal read"
28333
28334 test_400a() { # LU-1606, was conf-sanity test_74
28335         if ! which $CC > /dev/null 2>&1; then
28336                 skip_env "$CC is not installed"
28337         fi
28338
28339         local extra_flags=''
28340         local out=$TMP/$tfile
28341         local prefix=/usr/include/lustre
28342         local prog
28343
28344         # Oleg removes .c files in his test rig so test if any c files exist
28345         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28346                 skip_env "Needed .c test files are missing"
28347
28348         if ! [[ -d $prefix ]]; then
28349                 # Assume we're running in tree and fixup the include path.
28350                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28351                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28352                 extra_flags+=" -L$LUSTRE/utils/.libs"
28353         fi
28354
28355         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28356                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28357                         error "client api broken"
28358         done
28359         rm -f $out
28360 }
28361 run_test 400a "Lustre client api program can compile and link"
28362
28363 test_400b() { # LU-1606, LU-5011
28364         local header
28365         local out=$TMP/$tfile
28366         local prefix=/usr/include/linux/lustre
28367
28368         # We use a hard coded prefix so that this test will not fail
28369         # when run in tree. There are headers in lustre/include/lustre/
28370         # that are not packaged (like lustre_idl.h) and have more
28371         # complicated include dependencies (like config.h and lnet/types.h).
28372         # Since this test about correct packaging we just skip them when
28373         # they don't exist (see below) rather than try to fixup cppflags.
28374
28375         if ! which $CC > /dev/null 2>&1; then
28376                 skip_env "$CC is not installed"
28377         fi
28378
28379         for header in $prefix/*.h; do
28380                 if ! [[ -f "$header" ]]; then
28381                         continue
28382                 fi
28383
28384                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28385                         continue # lustre_ioctl.h is internal header
28386                 fi
28387
28388                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28389                         error "cannot compile '$header'"
28390         done
28391         rm -f $out
28392 }
28393 run_test 400b "packaged headers can be compiled"
28394
28395 test_401a() { #LU-7437
28396         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28397         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28398
28399         #count the number of parameters by "list_param -R"
28400         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28401         #count the number of parameters by listing proc files
28402         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28403         echo "proc_dirs='$proc_dirs'"
28404         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28405         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28406                       sort -u | wc -l)
28407
28408         [ $params -eq $procs ] ||
28409                 error "found $params parameters vs. $procs proc files"
28410
28411         # test the list_param -D option only returns directories
28412         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28413         #count the number of parameters by listing proc directories
28414         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28415                 sort -u | wc -l)
28416
28417         [ $params -eq $procs ] ||
28418                 error "found $params parameters vs. $procs proc files"
28419 }
28420 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28421
28422 test_401b() {
28423         # jobid_var may not allow arbitrary values, so use jobid_name
28424         # if available
28425         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28426                 local testname=jobid_name tmp='testing%p'
28427         else
28428                 local testname=jobid_var tmp=testing
28429         fi
28430
28431         local save=$($LCTL get_param -n $testname)
28432
28433         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28434                 error "no error returned when setting bad parameters"
28435
28436         local jobid_new=$($LCTL get_param -n foe $testname baz)
28437         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28438
28439         $LCTL set_param -n fog=bam $testname=$save bat=fog
28440         local jobid_old=$($LCTL get_param -n foe $testname bag)
28441         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28442 }
28443 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28444
28445 test_401c() {
28446         # jobid_var may not allow arbitrary values, so use jobid_name
28447         # if available
28448         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28449                 local testname=jobid_name
28450         else
28451                 local testname=jobid_var
28452         fi
28453
28454         local jobid_var_old=$($LCTL get_param -n $testname)
28455         local jobid_var_new
28456
28457         $LCTL set_param $testname= &&
28458                 error "no error returned for 'set_param a='"
28459
28460         jobid_var_new=$($LCTL get_param -n $testname)
28461         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28462                 error "$testname was changed by setting without value"
28463
28464         $LCTL set_param $testname &&
28465                 error "no error returned for 'set_param a'"
28466
28467         jobid_var_new=$($LCTL get_param -n $testname)
28468         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28469                 error "$testname was changed by setting without value"
28470 }
28471 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28472
28473 test_401d() {
28474         # jobid_var may not allow arbitrary values, so use jobid_name
28475         # if available
28476         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28477                 local testname=jobid_name new_value='foo=bar%p'
28478         else
28479                 local testname=jobid_var new_valuie=foo=bar
28480         fi
28481
28482         local jobid_var_old=$($LCTL get_param -n $testname)
28483         local jobid_var_new
28484
28485         $LCTL set_param $testname=$new_value ||
28486                 error "'set_param a=b' did not accept a value containing '='"
28487
28488         jobid_var_new=$($LCTL get_param -n $testname)
28489         [[ "$jobid_var_new" == "$new_value" ]] ||
28490                 error "'set_param a=b' failed on a value containing '='"
28491
28492         # Reset the $testname to test the other format
28493         $LCTL set_param $testname=$jobid_var_old
28494         jobid_var_new=$($LCTL get_param -n $testname)
28495         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28496                 error "failed to reset $testname"
28497
28498         $LCTL set_param $testname $new_value ||
28499                 error "'set_param a b' did not accept a value containing '='"
28500
28501         jobid_var_new=$($LCTL get_param -n $testname)
28502         [[ "$jobid_var_new" == "$new_value" ]] ||
28503                 error "'set_param a b' failed on a value containing '='"
28504
28505         $LCTL set_param $testname $jobid_var_old
28506         jobid_var_new=$($LCTL get_param -n $testname)
28507         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28508                 error "failed to reset $testname"
28509 }
28510 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28511
28512 test_401e() { # LU-14779
28513         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28514                 error "lctl list_param MGC* failed"
28515         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28516         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28517                 error "lctl get_param lru_size failed"
28518 }
28519 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28520
28521 test_402() {
28522         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28523         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28524                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28525         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28526                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28527                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28528         remote_mds_nodsh && skip "remote MDS with nodsh"
28529
28530         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28531 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28532         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28533         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28534                 echo "Touch failed - OK"
28535 }
28536 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28537
28538 test_403() {
28539         local file1=$DIR/$tfile.1
28540         local file2=$DIR/$tfile.2
28541         local tfile=$TMP/$tfile
28542
28543         rm -f $file1 $file2 $tfile
28544
28545         touch $file1
28546         ln $file1 $file2
28547
28548         # 30 sec OBD_TIMEOUT in ll_getattr()
28549         # right before populating st_nlink
28550         $LCTL set_param fail_loc=0x80001409
28551         stat -c %h $file1 > $tfile &
28552
28553         # create an alias, drop all locks and reclaim the dentry
28554         < $file2
28555         cancel_lru_locks mdc
28556         cancel_lru_locks osc
28557         sysctl -w vm.drop_caches=2
28558
28559         wait
28560
28561         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28562
28563         rm -f $tfile $file1 $file2
28564 }
28565 run_test 403 "i_nlink should not drop to zero due to aliasing"
28566
28567 test_404() { # LU-6601
28568         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28569                 skip "Need server version newer than 2.8.52"
28570         remote_mds_nodsh && skip "remote MDS with nodsh"
28571
28572         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28573                 awk '/osp .*-osc-MDT/ { print $4}')
28574
28575         local osp
28576         for osp in $mosps; do
28577                 echo "Deactivate: " $osp
28578                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28579                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28580                         awk -vp=$osp '$4 == p { print $2 }')
28581                 [ $stat = IN ] || {
28582                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28583                         error "deactivate error"
28584                 }
28585                 echo "Activate: " $osp
28586                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28587                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28588                         awk -vp=$osp '$4 == p { print $2 }')
28589                 [ $stat = UP ] || {
28590                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28591                         error "activate error"
28592                 }
28593         done
28594 }
28595 run_test 404 "validate manual {de}activated works properly for OSPs"
28596
28597 test_405() {
28598         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28599         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28600                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28601                         skip "Layout swap lock is not supported"
28602
28603         check_swap_layouts_support
28604         check_swap_layout_no_dom $DIR
28605
28606         test_mkdir $DIR/$tdir
28607         swap_lock_test -d $DIR/$tdir ||
28608                 error "One layout swap locked test failed"
28609 }
28610 run_test 405 "Various layout swap lock tests"
28611
28612 test_406() {
28613         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28614         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28615         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28617         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28618                 skip "Need MDS version at least 2.8.50"
28619
28620         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28621         local test_pool=$TESTNAME
28622
28623         pool_add $test_pool || error "pool_add failed"
28624         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28625                 error "pool_add_targets failed"
28626
28627         save_layout_restore_at_exit $MOUNT
28628
28629         # parent set default stripe count only, child will stripe from both
28630         # parent and fs default
28631         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28632                 error "setstripe $MOUNT failed"
28633         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28634         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28635         for i in $(seq 10); do
28636                 local f=$DIR/$tdir/$tfile.$i
28637                 touch $f || error "touch failed"
28638                 local count=$($LFS getstripe -c $f)
28639                 [ $count -eq $OSTCOUNT ] ||
28640                         error "$f stripe count $count != $OSTCOUNT"
28641                 local offset=$($LFS getstripe -i $f)
28642                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28643                 local size=$($LFS getstripe -S $f)
28644                 [ $size -eq $((def_stripe_size * 2)) ] ||
28645                         error "$f stripe size $size != $((def_stripe_size * 2))"
28646                 local pool=$($LFS getstripe -p $f)
28647                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28648         done
28649
28650         # change fs default striping, delete parent default striping, now child
28651         # will stripe from new fs default striping only
28652         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28653                 error "change $MOUNT default stripe failed"
28654         $LFS setstripe -c 0 $DIR/$tdir ||
28655                 error "delete $tdir default stripe failed"
28656         for i in $(seq 11 20); do
28657                 local f=$DIR/$tdir/$tfile.$i
28658                 touch $f || error "touch $f failed"
28659                 local count=$($LFS getstripe -c $f)
28660                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28661                 local offset=$($LFS getstripe -i $f)
28662                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28663                 local size=$($LFS getstripe -S $f)
28664                 [ $size -eq $def_stripe_size ] ||
28665                         error "$f stripe size $size != $def_stripe_size"
28666                 local pool=$($LFS getstripe -p $f)
28667                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28668         done
28669
28670         unlinkmany $DIR/$tdir/$tfile. 1 20
28671
28672         local f=$DIR/$tdir/$tfile
28673         pool_remove_all_targets $test_pool $f
28674         pool_remove $test_pool $f
28675 }
28676 run_test 406 "DNE support fs default striping"
28677
28678 test_407() {
28679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28680         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28681                 skip "Need MDS version at least 2.8.55"
28682         remote_mds_nodsh && skip "remote MDS with nodsh"
28683
28684         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28685                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28686         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28687                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28688         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28689
28690         #define OBD_FAIL_DT_TXN_STOP    0x2019
28691         for idx in $(seq $MDSCOUNT); do
28692                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28693         done
28694         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28695         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28696                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28697         true
28698 }
28699 run_test 407 "transaction fail should cause operation fail"
28700
28701 test_408() {
28702         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28703
28704         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28705         lctl set_param fail_loc=0x8000040a
28706         # let ll_prepare_partial_page() fail
28707         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28708
28709         rm -f $DIR/$tfile
28710
28711         # create at least 100 unused inodes so that
28712         # shrink_icache_memory(0) should not return 0
28713         touch $DIR/$tfile-{0..100}
28714         rm -f $DIR/$tfile-{0..100}
28715         sync
28716
28717         echo 2 > /proc/sys/vm/drop_caches
28718 }
28719 run_test 408 "drop_caches should not hang due to page leaks"
28720
28721 test_409()
28722 {
28723         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28724
28725         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28726         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28727         touch $DIR/$tdir/guard || error "(2) Fail to create"
28728
28729         local PREFIX=$(str_repeat 'A' 128)
28730         echo "Create 1K hard links start at $(date)"
28731         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28732                 error "(3) Fail to hard link"
28733
28734         echo "Links count should be right although linkEA overflow"
28735         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28736         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28737         [ $linkcount -eq 1001 ] ||
28738                 error "(5) Unexpected hard links count: $linkcount"
28739
28740         echo "List all links start at $(date)"
28741         ls -l $DIR/$tdir/foo > /dev/null ||
28742                 error "(6) Fail to list $DIR/$tdir/foo"
28743
28744         echo "Unlink hard links start at $(date)"
28745         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28746                 error "(7) Fail to unlink"
28747         echo "Unlink hard links finished at $(date)"
28748 }
28749 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28750
28751 test_410()
28752 {
28753         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28754                 skip "Need client version at least 2.9.59"
28755
28756         # Create a file, and stat it from the kernel
28757         local testfile=$DIR/$tfile
28758         touch $testfile
28759
28760         local run_id=$RANDOM
28761         local my_ino=$(stat --format "%i" $testfile)
28762
28763         # Try to insert the module.
28764         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28765                 error "load_module failed"
28766
28767         # Anything but success is a test failure
28768         dmesg | grep -q \
28769             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28770             error "no inode match"
28771
28772         # Remove the test module
28773         rmmod -v kinode ||
28774                 error "rmmod failed (may trigger a failure in a later test)"
28775 }
28776 run_test 410 "Test inode number returned from kernel thread"
28777
28778 cleanup_test411_cgroup() {
28779         trap 0
28780         cat $1/memory.stat
28781         rmdir "$1"
28782 }
28783
28784 test_411a() {
28785         local cg_basedir=/sys/fs/cgroup/memory
28786         # LU-9966
28787         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28788                 skip "no setup for cgroup"
28789
28790         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28791                 error "test file creation failed"
28792         cancel_lru_locks osc
28793
28794         # Create a very small memory cgroup to force a slab allocation error
28795         local cgdir=$cg_basedir/osc_slab_alloc
28796         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28797         trap "cleanup_test411_cgroup $cgdir" EXIT
28798         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28799         echo 1M > $cgdir/memory.limit_in_bytes
28800
28801         # Should not LBUG, just be killed by oom-killer
28802         # dd will return 0 even allocation failure in some environment.
28803         # So don't check return value
28804         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28805         cleanup_test411_cgroup $cgdir
28806
28807         return 0
28808 }
28809 run_test 411a "Slab allocation error with cgroup does not LBUG"
28810
28811 test_411b() {
28812         local cg_basedir=/sys/fs/cgroup/memory
28813         # LU-9966
28814         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28815                 skip "no setup for cgroup"
28816         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28817         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28818         # limit, so we have 384M in cgroup
28819         # (arm) this seems to hit OOM more often than x86, so 1024M
28820         if [[ $(uname -m) = aarch64 ]]; then
28821                 local memlimit_mb=1024
28822         else
28823                 local memlimit_mb=384
28824         fi
28825
28826         # Create a cgroup and set memory limit
28827         # (tfile is used as an easy way to get a recognizable cgroup name)
28828         local cgdir=$cg_basedir/$tfile
28829         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28830         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28831         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28832
28833         echo "writing first file"
28834         # Write a file 4x the memory limit in size
28835         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28836                 error "(1) failed to write successfully"
28837
28838         sync
28839         cancel_lru_locks osc
28840
28841         rm -f $DIR/$tfile
28842         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28843
28844         # Try writing at a larger block size
28845         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28846         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28847         # need *some* memory to do IO in)
28848         echo "writing at larger block size"
28849         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28850                 error "(3) failed to write successfully"
28851
28852         sync
28853         cancel_lru_locks osc
28854         rm -f $DIR/$tfile
28855         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28856
28857         # Try writing multiple files at once
28858         echo "writing multiple files"
28859         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28860         local pid1=$!
28861         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28862         local pid2=$!
28863         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28864         local pid3=$!
28865         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28866         local pid4=$!
28867
28868         wait $pid1
28869         local rc1=$?
28870         wait $pid2
28871         local rc2=$?
28872         wait $pid3
28873         local rc3=$?
28874         wait $pid4
28875         local rc4=$?
28876         if (( rc1 != 0)); then
28877                 error "error $rc1 writing to file from $pid1"
28878         fi
28879         if (( rc2 != 0)); then
28880                 error "error $rc2 writing to file from $pid2"
28881         fi
28882         if (( rc3 != 0)); then
28883                 error "error $rc3 writing to file from $pid3"
28884         fi
28885         if (( rc4 != 0)); then
28886                 error "error $rc4 writing to file from $pid4"
28887         fi
28888
28889         sync
28890         cancel_lru_locks osc
28891
28892         # These files can be large-ish (~1 GiB total), so delete them rather
28893         # than leave for later cleanup
28894         rm -f $DIR/$tfile.*
28895         return 0
28896 }
28897 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28898
28899 test_412() {
28900         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28901         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28902                 skip "Need server version at least 2.10.55"
28903
28904         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28905                 error "mkdir failed"
28906         $LFS getdirstripe $DIR/$tdir
28907         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28908         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28909                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28910         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28911         [ $stripe_count -eq 2 ] ||
28912                 error "expect 2 get $stripe_count"
28913
28914         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28915
28916         local index
28917         local index2
28918
28919         # subdirs should be on the same MDT as parent
28920         for i in $(seq 0 $((MDSCOUNT - 1))); do
28921                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28922                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28923                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28924                 (( index == i )) || error "mdt$i/sub on MDT$index"
28925         done
28926
28927         # stripe offset -1, ditto
28928         for i in {1..10}; do
28929                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28930                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28931                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28932                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28933                 (( index == index2 )) ||
28934                         error "qos$i on MDT$index, sub on MDT$index2"
28935         done
28936
28937         local testdir=$DIR/$tdir/inherit
28938
28939         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28940         # inherit 2 levels
28941         for i in 1 2; do
28942                 testdir=$testdir/s$i
28943                 mkdir $testdir || error "mkdir $testdir failed"
28944                 index=$($LFS getstripe -m $testdir)
28945                 (( index == 1 )) ||
28946                         error "$testdir on MDT$index"
28947         done
28948
28949         # not inherit any more
28950         testdir=$testdir/s3
28951         mkdir $testdir || error "mkdir $testdir failed"
28952         getfattr -d -m dmv $testdir | grep dmv &&
28953                 error "default LMV set on $testdir" || true
28954 }
28955 run_test 412 "mkdir on specific MDTs"
28956
28957 TEST413_COUNT=${TEST413_COUNT:-200}
28958
28959 #
28960 # set_maxage() is used by test_413 only.
28961 # This is a helper function to set maxage. Does not return any value.
28962 # Input: maxage to set
28963 #
28964 set_maxage() {
28965         local lmv_qos_maxage
28966         local lod_qos_maxage
28967         local new_maxage=$1
28968
28969         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28970         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28971         stack_trap "$LCTL set_param \
28972                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28973         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28974                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28975         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28976                 lod.*.mdt_qos_maxage=$new_maxage
28977         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28978                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28979 }
28980
28981 generate_uneven_mdts() {
28982         local threshold=$1
28983         local ffree
28984         local bavail
28985         local max
28986         local min
28987         local max_index
28988         local min_index
28989         local tmp
28990         local i
28991
28992         echo
28993         echo "Check for uneven MDTs: "
28994
28995         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28996         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28997         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28998
28999         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29000         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29001         max_index=0
29002         min_index=0
29003         for ((i = 1; i < ${#ffree[@]}; i++)); do
29004                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29005                 if [ $tmp -gt $max ]; then
29006                         max=$tmp
29007                         max_index=$i
29008                 fi
29009                 if [ $tmp -lt $min ]; then
29010                         min=$tmp
29011                         min_index=$i
29012                 fi
29013         done
29014
29015         (( min > 0 )) || skip "low space on MDT$min_index"
29016         (( ${ffree[min_index]} > 0 )) ||
29017                 skip "no free files on MDT$min_index"
29018         (( ${ffree[min_index]} < 10000000 )) ||
29019                 skip "too many free files on MDT$min_index"
29020
29021         # Check if we need to generate uneven MDTs
29022         local diff=$(((max - min) * 100 / min))
29023         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
29024         local testdir # individual folder within $testdirp
29025         local start
29026         local cmd
29027
29028         # fallocate is faster to consume space on MDT, if available
29029         if check_fallocate_supported mds$((min_index + 1)); then
29030                 cmd="fallocate -l 128K "
29031         else
29032                 cmd="dd if=/dev/zero bs=128K count=1 of="
29033         fi
29034
29035         echo "using cmd $cmd"
29036         for (( i = 0; diff < threshold; i++ )); do
29037                 testdir=${testdirp}/$i
29038                 [ -d $testdir ] && continue
29039
29040                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
29041
29042                 mkdir -p $testdirp
29043                 # generate uneven MDTs, create till $threshold% diff
29044                 echo -n "weight diff=$diff% must be > $threshold% ..."
29045                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
29046                 $LFS mkdir -i $min_index $testdir ||
29047                         error "mkdir $testdir failed"
29048                 $LFS setstripe -E 1M -L mdt $testdir ||
29049                         error "setstripe $testdir failed"
29050                 start=$SECONDS
29051                 for (( f = 0; f < TEST413_COUNT; f++ )); do
29052                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
29053                 done
29054                 sync; sleep 1; sync
29055
29056                 # wait for QOS to update
29057                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
29058
29059                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
29060                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
29061                 max=$(((${ffree[max_index]} >> 8) *
29062                         (${bavail[max_index]} * bsize >> 16)))
29063                 min=$(((${ffree[min_index]} >> 8) *
29064                         (${bavail[min_index]} * bsize >> 16)))
29065                 (( min > 0 )) || skip "low space on MDT$min_index"
29066                 diff=$(((max - min) * 100 / min))
29067         done
29068
29069         echo "MDT filesfree available: ${ffree[*]}"
29070         echo "MDT blocks available: ${bavail[*]}"
29071         echo "weight diff=$diff%"
29072 }
29073
29074 test_qos_mkdir() {
29075         local mkdir_cmd=$1
29076         local stripe_count=$2
29077         local mdts=$(comma_list $(mdts_nodes))
29078
29079         local testdir
29080         local lmv_qos_prio_free
29081         local lmv_qos_threshold_rr
29082         local lod_qos_prio_free
29083         local lod_qos_threshold_rr
29084         local total
29085         local count
29086         local i
29087
29088         # @total is total directories created if it's testing plain
29089         # directories, otherwise it's total stripe object count for
29090         # striped directories test.
29091         # remote/striped directory unlinking is slow on zfs and may
29092         # timeout, test with fewer directories
29093         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
29094
29095         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
29096         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
29097         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29098                 head -n1)
29099         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
29100         stack_trap "$LCTL set_param \
29101                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
29102         stack_trap "$LCTL set_param \
29103                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
29104
29105         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
29106                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
29107         lod_qos_prio_free=${lod_qos_prio_free%%%}
29108         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
29109                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
29110         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
29111         stack_trap "do_nodes $mdts $LCTL set_param \
29112                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
29113         stack_trap "do_nodes $mdts $LCTL set_param \
29114                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
29115
29116         # decrease statfs age, so that it can be updated in time
29117         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
29118         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
29119
29120         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29121         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
29122
29123         testdir=$DIR/$tdir-s$stripe_count/rr
29124
29125         local stripe_index=$($LFS getstripe -m $testdir)
29126         local test_mkdir_rr=true
29127
29128         getfattr -d -m dmv -e hex $testdir | grep dmv
29129         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
29130                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
29131                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
29132                         test_mkdir_rr=false
29133         fi
29134
29135         echo
29136         $test_mkdir_rr &&
29137                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
29138                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
29139
29140         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29141         for (( i = 0; i < total / stripe_count; i++ )); do
29142                 eval $mkdir_cmd $testdir/subdir$i ||
29143                         error "$mkdir_cmd subdir$i failed"
29144         done
29145
29146         for (( i = 0; i < $MDSCOUNT; i++ )); do
29147                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29148                 echo "$count directories created on MDT$i"
29149                 if $test_mkdir_rr; then
29150                         (( count == total / stripe_count / MDSCOUNT )) ||
29151                                 error "subdirs are not evenly distributed"
29152                 elif (( i == stripe_index )); then
29153                         (( count == total / stripe_count )) ||
29154                                 error "$count subdirs created on MDT$i"
29155                 else
29156                         (( count == 0 )) ||
29157                                 error "$count subdirs created on MDT$i"
29158                 fi
29159
29160                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
29161                         count=$($LFS getdirstripe $testdir/* |
29162                                 grep -c -P "^\s+$i\t")
29163                         echo "$count stripes created on MDT$i"
29164                         # deviation should < 5% of average
29165                         delta=$((count - total / MDSCOUNT))
29166                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
29167                                 error "stripes are not evenly distributed"
29168                 fi
29169         done
29170
29171         echo
29172         echo "Check for uneven MDTs: "
29173
29174         local ffree
29175         local bavail
29176         local max
29177         local min
29178         local max_index
29179         local min_index
29180         local tmp
29181
29182         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29183         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29184         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29185
29186         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29187         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29188         max_index=0
29189         min_index=0
29190         for ((i = 1; i < ${#ffree[@]}; i++)); do
29191                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29192                 if [ $tmp -gt $max ]; then
29193                         max=$tmp
29194                         max_index=$i
29195                 fi
29196                 if [ $tmp -lt $min ]; then
29197                         min=$tmp
29198                         min_index=$i
29199                 fi
29200         done
29201         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29202
29203         (( min > 0 )) || skip "low space on MDT$min_index"
29204         (( ${ffree[min_index]} < 10000000 )) ||
29205                 skip "too many free files on MDT$min_index"
29206
29207         generate_uneven_mdts 120
29208
29209         echo "MDT filesfree available: ${ffree[*]}"
29210         echo "MDT blocks available: ${bavail[*]}"
29211         echo "weight diff=$(((max - min) * 100 / min))%"
29212         echo
29213         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29214
29215         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29216         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29217         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29218         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29219
29220         sleep 1
29221
29222         testdir=$DIR/$tdir-s$stripe_count/qos
29223
29224         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29225         for (( i = 0; i < total / stripe_count; i++ )); do
29226                 eval $mkdir_cmd $testdir/subdir$i ||
29227                         error "$mkdir_cmd subdir$i failed"
29228         done
29229
29230         max=0
29231         for (( i = 0; i < $MDSCOUNT; i++ )); do
29232                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29233                 (( count > max )) && max=$count
29234                 echo "$count directories created on MDT$i : curmax=$max"
29235         done
29236
29237         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29238
29239         # D-value should > 10% of average
29240         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29241                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29242
29243         # ditto for stripes
29244         if (( stripe_count > 1 )); then
29245                 max=0
29246                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29247                         count=$($LFS getdirstripe $testdir/* |
29248                                 grep -c -P "^\s+$i\t")
29249                         (( count > max )) && max=$count
29250                         echo "$count stripes created on MDT$i"
29251                 done
29252
29253                 min=$($LFS getdirstripe $testdir/* |
29254                         grep -c -P "^\s+$min_index\t")
29255                 (( max - min > total / MDSCOUNT / 10 )) ||
29256                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29257         fi
29258 }
29259
29260 most_full_mdt() {
29261         local ffree
29262         local bavail
29263         local bsize
29264         local min
29265         local min_index
29266         local tmp
29267
29268         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29269         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29270         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29271
29272         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29273         min_index=0
29274         for ((i = 1; i < ${#ffree[@]}; i++)); do
29275                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29276                 (( tmp < min )) && min=$tmp && min_index=$i
29277         done
29278
29279         echo -n $min_index
29280 }
29281
29282 test_413a() {
29283         [ $MDSCOUNT -lt 2 ] &&
29284                 skip "We need at least 2 MDTs for this test"
29285
29286         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29287                 skip "Need server version at least 2.12.52"
29288
29289         local stripe_max=$((MDSCOUNT - 1))
29290         local stripe_count
29291
29292         # let caller set maxage for latest result
29293         set_maxage 1
29294
29295         # fill MDT unevenly
29296         generate_uneven_mdts 120
29297
29298         # test 4-stripe directory at most, otherwise it's too slow
29299         # We are being very defensive. Although Autotest uses 4 MDTs.
29300         # We make sure stripe_max does not go over 4.
29301         (( stripe_max > 4 )) && stripe_max=4
29302         # unlinking striped directory is slow on zfs, and may timeout, only test
29303         # plain directory
29304         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29305         for stripe_count in $(seq 1 $stripe_max); do
29306                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29307                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29308                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29309                         error "mkdir failed"
29310                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29311         done
29312 }
29313 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29314
29315 test_413b() {
29316         [ $MDSCOUNT -lt 2 ] &&
29317                 skip "We need at least 2 MDTs for this test"
29318
29319         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29320                 skip "Need server version at least 2.12.52"
29321
29322         local stripe_max=$((MDSCOUNT - 1))
29323         local testdir
29324         local stripe_count
29325
29326         # let caller set maxage for latest result
29327         set_maxage 1
29328
29329         # fill MDT unevenly
29330         generate_uneven_mdts 120
29331
29332         # test 4-stripe directory at most, otherwise it's too slow
29333         # We are being very defensive. Although Autotest uses 4 MDTs.
29334         # We make sure stripe_max does not go over 4.
29335         (( stripe_max > 4 )) && stripe_max=4
29336         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29337         for stripe_count in $(seq 1 $stripe_max); do
29338                 testdir=$DIR/$tdir-s$stripe_count
29339                 mkdir $testdir || error "mkdir $testdir failed"
29340                 mkdir $testdir/rr || error "mkdir rr failed"
29341                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29342                         error "mkdir qos failed"
29343                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29344                         $testdir/rr || error "setdirstripe rr failed"
29345                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29346                         error "setdirstripe failed"
29347                 test_qos_mkdir "mkdir" $stripe_count
29348         done
29349 }
29350 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29351
29352 test_413c() {
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 testdir
29360         local inherit
29361         local inherit_rr
29362         local lmv_qos_maxage
29363         local lod_qos_maxage
29364
29365         # let caller set maxage for latest result
29366         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29367         $LCTL set_param lmv.*.qos_maxage=1
29368         stack_trap "$LCTL set_param \
29369                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29370         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29371                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29372         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29373                 lod.*.mdt_qos_maxage=1
29374         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29375                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29376
29377         # fill MDT unevenly
29378         generate_uneven_mdts 120
29379
29380         testdir=$DIR/${tdir}-s1
29381         mkdir $testdir || error "mkdir $testdir failed"
29382         mkdir $testdir/rr || error "mkdir rr failed"
29383         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29384         # default max_inherit is -1, default max_inherit_rr is 0
29385         $LFS setdirstripe -D -c 1 $testdir/rr ||
29386                 error "setdirstripe rr failed"
29387         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29388                 error "setdirstripe qos failed"
29389         test_qos_mkdir "mkdir" 1
29390
29391         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29392         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29393         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29394         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29395         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29396
29397         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29398         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29399         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29400         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29401         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29402         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29403         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29404                 error "level2 shouldn't have default LMV" || true
29405 }
29406 run_test 413c "mkdir with default LMV max inherit rr"
29407
29408 test_413d() {
29409         (( MDSCOUNT >= 2 )) ||
29410                 skip "We need at least 2 MDTs for this test"
29411
29412         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29413                 skip "Need server version at least 2.14.51"
29414
29415         local lmv_qos_threshold_rr
29416
29417         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29418                 head -n1)
29419         stack_trap "$LCTL set_param \
29420                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29421
29422         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29423         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29424         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29425                 error "$tdir shouldn't have default LMV"
29426         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29427                 error "mkdir sub failed"
29428
29429         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29430
29431         (( count == 100 )) || error "$count subdirs on MDT0"
29432 }
29433 run_test 413d "inherit ROOT default LMV"
29434
29435 test_413e() {
29436         (( MDSCOUNT >= 2 )) ||
29437                 skip "We need at least 2 MDTs for this test"
29438         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29439                 skip "Need server version at least 2.14.55"
29440
29441         local testdir=$DIR/$tdir
29442         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29443         local max_inherit
29444         local sub_max_inherit
29445
29446         mkdir -p $testdir || error "failed to create $testdir"
29447
29448         # set default max-inherit to -1 if stripe count is 0 or 1
29449         $LFS setdirstripe -D -c 1 $testdir ||
29450                 error "failed to set default LMV"
29451         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29452         (( max_inherit == -1 )) ||
29453                 error "wrong max_inherit value $max_inherit"
29454
29455         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29456         $LFS setdirstripe -D -c -1 $testdir ||
29457                 error "failed to set default LMV"
29458         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29459         (( max_inherit > 0 )) ||
29460                 error "wrong max_inherit value $max_inherit"
29461
29462         # and the subdir will decrease the max_inherit by 1
29463         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29464         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29465         (( sub_max_inherit == max_inherit - 1)) ||
29466                 error "wrong max-inherit of subdir $sub_max_inherit"
29467
29468         # check specified --max-inherit and warning message
29469         stack_trap "rm -f $tmpfile"
29470         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29471                 error "failed to set default LMV"
29472         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29473         (( max_inherit == -1 )) ||
29474                 error "wrong max_inherit value $max_inherit"
29475
29476         # check the warning messages
29477         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29478                 error "failed to detect warning string"
29479         fi
29480 }
29481 run_test 413e "check default max-inherit value"
29482
29483 test_fs_dmv_inherit()
29484 {
29485         local testdir=$DIR/$tdir
29486
29487         local count
29488         local inherit
29489         local inherit_rr
29490
29491         for i in 1 2; do
29492                 mkdir $testdir || error "mkdir $testdir failed"
29493                 count=$($LFS getdirstripe -D -c $testdir)
29494                 (( count == 1 )) ||
29495                         error "$testdir default LMV count mismatch $count != 1"
29496                 inherit=$($LFS getdirstripe -D -X $testdir)
29497                 (( inherit == 3 - i )) ||
29498                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29499                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29500                 (( inherit_rr == 3 - i )) ||
29501                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29502                 testdir=$testdir/sub
29503         done
29504
29505         mkdir $testdir || error "mkdir $testdir failed"
29506         count=$($LFS getdirstripe -D -c $testdir)
29507         (( count == 0 )) ||
29508                 error "$testdir default LMV count not zero: $count"
29509 }
29510
29511 test_413f() {
29512         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29513
29514         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29515                 skip "Need server version at least 2.14.55"
29516
29517         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29518                 error "dump $DIR default LMV failed"
29519         stack_trap "setfattr --restore=$TMP/dmv.ea"
29520
29521         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29522                 error "set $DIR default LMV failed"
29523
29524         test_fs_dmv_inherit
29525 }
29526 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29527
29528 test_413g() {
29529         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29530
29531         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29532         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29533                 error "dump $DIR default LMV failed"
29534         stack_trap "setfattr --restore=$TMP/dmv.ea"
29535
29536         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29537                 error "set $DIR default LMV failed"
29538
29539         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29540                 error "mount $MOUNT2 failed"
29541         stack_trap "umount_client $MOUNT2"
29542
29543         local saved_DIR=$DIR
29544
29545         export DIR=$MOUNT2
29546
29547         stack_trap "export DIR=$saved_DIR"
29548
29549         # first check filesystem-wide default LMV inheritance
29550         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29551
29552         # then check subdirs are spread to all MDTs
29553         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29554
29555         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29556
29557         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29558 }
29559 run_test 413g "enforce ROOT default LMV on subdir mount"
29560
29561 test_413h() {
29562         (( MDSCOUNT >= 2 )) ||
29563                 skip "We need at least 2 MDTs for this test"
29564
29565         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29566                 skip "Need server version at least 2.15.50.6"
29567
29568         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29569
29570         stack_trap "$LCTL set_param \
29571                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29572         $LCTL set_param lmv.*.qos_maxage=1
29573
29574         local depth=5
29575         local rr_depth=4
29576         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29577         local count=$((MDSCOUNT * 20))
29578
29579         generate_uneven_mdts 50
29580
29581         mkdir -p $dir || error "mkdir $dir failed"
29582         stack_trap "rm -rf $dir"
29583         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29584                 --max-inherit-rr=$rr_depth $dir
29585
29586         for ((d=0; d < depth + 2; d++)); do
29587                 log "dir=$dir:"
29588                 for ((sub=0; sub < count; sub++)); do
29589                         mkdir $dir/d$sub
29590                 done
29591                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29592                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29593                 # subdirs within $rr_depth should be created round-robin
29594                 if (( d < rr_depth )); then
29595                         (( ${num[0]} != count )) ||
29596                                 error "all objects created on MDT ${num[1]}"
29597                 fi
29598
29599                 dir=$dir/d0
29600         done
29601 }
29602 run_test 413h "don't stick to parent for round-robin dirs"
29603
29604 test_413i() {
29605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29606
29607         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29608                 skip "Need server version at least 2.14.55"
29609
29610         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29611                 error "dump $DIR default LMV failed"
29612         stack_trap "setfattr --restore=$TMP/dmv.ea"
29613
29614         local testdir=$DIR/$tdir
29615         local def_max_rr=1
29616         local def_max=3
29617         local count
29618
29619         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29620                 --max-inherit-rr=$def_max_rr $DIR ||
29621                 error "set $DIR default LMV failed"
29622
29623         for i in $(seq 2 3); do
29624                 def_max=$((def_max - 1))
29625                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29626
29627                 mkdir $testdir
29628                 # RR is decremented and keeps zeroed once exhausted
29629                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29630                 (( count == def_max_rr )) ||
29631                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29632
29633                 # max-inherit is decremented
29634                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29635                 (( count == def_max )) ||
29636                         error_noexit "$testdir: max-inherit $count != $def_max"
29637
29638                 testdir=$testdir/d$i
29639         done
29640
29641         # d3 is the last inherited from ROOT, no inheritance anymore
29642         # i.e. no the default layout anymore
29643         mkdir -p $testdir/d4/d5
29644         count=$($LFS getdirstripe -D --max-inherit $testdir)
29645         (( count == -1 )) ||
29646                 error_noexit "$testdir: max-inherit $count != -1"
29647
29648         local p_count=$($LFS getdirstripe -i $testdir)
29649
29650         for i in $(seq 4 5); do
29651                 testdir=$testdir/d$i
29652
29653                 # the root default layout is not applied once exhausted
29654                 count=$($LFS getdirstripe -i $testdir)
29655                 (( count == p_count )) ||
29656                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29657         done
29658
29659         $LFS setdirstripe -i 0 $DIR/d2
29660         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29661         (( count == -1 )) ||
29662                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29663 }
29664 run_test 413i "check default layout inheritance"
29665
29666 test_413j()
29667 {
29668         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29669
29670         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29671         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29672                 error "setdirstripe $tdir failed"
29673
29674         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29675                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29676
29677         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29678         # setfattr dmv calls setdirstripe -D
29679         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29680                 error "setfattr sub failed"
29681         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29682                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29683
29684         [ $value == $value2 ] || error "dmv mismatch"
29685
29686         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29687
29688         # do not allow remove dmv by setfattr -x
29689         do_nodes $(comma_list $(mdts_nodes)) \
29690                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29691         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29692         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29693
29694         # allow remove dmv by setfattr -x
29695         do_nodes $(comma_list $(mdts_nodes)) \
29696                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29697         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29698         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29699         do_nodes $(comma_list $(mdts_nodes)) \
29700                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29701 }
29702 run_test 413j "set default LMV by setxattr"
29703
29704 test_413k() {
29705         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29706                 skip "Need server version at least 2.15.60"
29707
29708         local index1
29709         local index2
29710         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29711         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29712         local prefixes="abc:123:foo bar"
29713
29714         # add prefixes
29715         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29716         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29717
29718         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29719         index1=$($LFS getstripe -m $DIR/$tdir)
29720         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29721                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29722                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29723                 ((index1 == index2)) ||
29724                         error "$tdir on MDT$index1, $dname on MDT$index2"
29725         done
29726
29727         # remove prefixes
29728         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29729
29730         # total prefixes length > PAGE_SIZE can be printed correctly
29731         for c in {a..z}; do
29732                 prefixes=$(str_repeat $c 255)
29733                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29734         done
29735         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29736         ((count2 == count + 26)) ||
29737                 error "prefixes count $count2 != $((count + 26))"
29738 }
29739 run_test 413k "QoS mkdir exclude prefixes"
29740
29741 test_413z() {
29742         local pids=""
29743         local subdir
29744         local pid
29745
29746         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29747                 unlinkmany $subdir/f. $TEST413_COUNT &
29748                 pids="$pids $!"
29749         done
29750
29751         for pid in $pids; do
29752                 wait $pid
29753         done
29754
29755         true
29756 }
29757 run_test 413z "413 test cleanup"
29758
29759 test_414() {
29760 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29761         $LCTL set_param fail_loc=0x80000521
29762         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29763         rm -f $DIR/$tfile
29764         # This error path has sometimes left inflight requests dangling, so
29765         # test for this by remounting the client (umount will hang if there's
29766         # a dangling request)
29767         umount_client $MOUNT
29768         mount_client $MOUNT
29769 }
29770 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29771
29772 test_415() {
29773         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29774         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29775                 skip "Need server version at least 2.11.52"
29776
29777         # LU-11102
29778         local total=500
29779         local max=120
29780
29781         # this test may be slow on ZFS
29782         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29783
29784         # though this test is designed for striped directory, let's test normal
29785         # directory too since lock is always saved as CoS lock.
29786         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29787         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29788         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29789         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29790         wait_delete_completed_mds
29791
29792         # run a loop without concurrent touch to measure rename duration.
29793         # only for test debug/robustness, NOT part of COS functional test.
29794         local start_time=$SECONDS
29795         for ((i = 0; i < total; i++)); do
29796                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29797                         > /dev/null
29798         done
29799         local baseline=$((SECONDS - start_time))
29800         echo "rename $total files without 'touch' took $baseline sec"
29801
29802         (
29803                 while true; do
29804                         touch $DIR/$tdir
29805                 done
29806         ) &
29807         local setattr_pid=$!
29808
29809         # rename files back to original name so unlinkmany works
29810         start_time=$SECONDS
29811         for ((i = 0; i < total; i++)); do
29812                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29813                         > /dev/null
29814         done
29815         local duration=$((SECONDS - start_time))
29816
29817         kill -9 $setattr_pid
29818
29819         echo "rename $total files with 'touch' took $duration sec"
29820         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29821         (( duration <= max )) ||
29822                 error_not_in_vm "rename took $duration > $max sec"
29823 }
29824 run_test 415 "lock revoke is not missing"
29825
29826 test_416() {
29827         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29828                 skip "Need server version at least 2.11.55"
29829
29830         # define OBD_FAIL_OSD_TXN_START    0x19a
29831         do_facet mds1 lctl set_param fail_loc=0x19a
29832
29833         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29834
29835         true
29836 }
29837 run_test 416 "transaction start failure won't cause system hung"
29838
29839 cleanup_417() {
29840         trap 0
29841         do_nodes $(comma_list $(mdts_nodes)) \
29842                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29843         do_nodes $(comma_list $(mdts_nodes)) \
29844                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29845         do_nodes $(comma_list $(mdts_nodes)) \
29846                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29847 }
29848
29849 test_417() {
29850         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29851         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29852                 skip "Need MDS version at least 2.11.56"
29853
29854         trap cleanup_417 RETURN EXIT
29855
29856         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29857         do_nodes $(comma_list $(mdts_nodes)) \
29858                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29859         $LFS migrate -m 0 $DIR/$tdir.1 &&
29860                 error "migrate dir $tdir.1 should fail"
29861
29862         do_nodes $(comma_list $(mdts_nodes)) \
29863                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29864         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29865                 error "create remote dir $tdir.2 should fail"
29866
29867         do_nodes $(comma_list $(mdts_nodes)) \
29868                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29869         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29870                 error "create striped dir $tdir.3 should fail"
29871         true
29872 }
29873 run_test 417 "disable remote dir, striped dir and dir migration"
29874
29875 # Checks that the outputs of df [-i] and lfs df [-i] match
29876 #
29877 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29878 check_lfs_df() {
29879         local dir=$2
29880         local inodes
29881         local df_out
29882         local lfs_df_out
29883         local count
29884         local passed=false
29885
29886         # blocks or inodes
29887         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29888
29889         for count in {1..100}; do
29890                 do_nodes "$CLIENTS" \
29891                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29892                 sync; sleep 0.2
29893
29894                 # read the lines of interest
29895                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29896                         error "df $inodes $dir | tail -n +2 failed"
29897                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29898                         error "lfs df $inodes $dir | grep summary: failed"
29899
29900                 # skip first substrings of each output as they are different
29901                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29902                 # compare the two outputs
29903                 passed=true
29904                 #  skip "available" on MDT until LU-13997 is fixed.
29905                 #for i in {1..5}; do
29906                 for i in 1 2 4 5; do
29907                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29908                 done
29909                 $passed && break
29910         done
29911
29912         if ! $passed; then
29913                 df -P $inodes $dir
29914                 echo
29915                 lfs df $inodes $dir
29916                 error "df and lfs df $1 output mismatch: "      \
29917                       "df ${inodes}: ${df_out[*]}, "            \
29918                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29919         fi
29920 }
29921
29922 test_418() {
29923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29924
29925         local dir=$DIR/$tdir
29926         local numfiles=$((RANDOM % 4096 + 2))
29927         local numblocks=$((RANDOM % 256 + 1))
29928
29929         wait_delete_completed
29930         test_mkdir $dir
29931
29932         # check block output
29933         check_lfs_df blocks $dir
29934         # check inode output
29935         check_lfs_df inodes $dir
29936
29937         # create a single file and retest
29938         echo "Creating a single file and testing"
29939         createmany -o $dir/$tfile- 1 &>/dev/null ||
29940                 error "creating 1 file in $dir failed"
29941         check_lfs_df blocks $dir
29942         check_lfs_df inodes $dir
29943
29944         # create a random number of files
29945         echo "Creating $((numfiles - 1)) files and testing"
29946         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29947                 error "creating $((numfiles - 1)) files in $dir failed"
29948
29949         # write a random number of blocks to the first test file
29950         echo "Writing $numblocks 4K blocks and testing"
29951         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29952                 count=$numblocks &>/dev/null ||
29953                 error "dd to $dir/${tfile}-0 failed"
29954
29955         # retest
29956         check_lfs_df blocks $dir
29957         check_lfs_df inodes $dir
29958
29959         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29960                 error "unlinking $numfiles files in $dir failed"
29961 }
29962 run_test 418 "df and lfs df outputs match"
29963
29964 test_419()
29965 {
29966         local dir=$DIR/$tdir
29967
29968         mkdir -p $dir
29969         touch $dir/file
29970
29971         cancel_lru_locks mdc
29972
29973         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29974         $LCTL set_param fail_loc=0x1410
29975         cat $dir/file
29976         $LCTL set_param fail_loc=0
29977         rm -rf $dir
29978 }
29979 run_test 419 "Verify open file by name doesn't crash kernel"
29980
29981 test_420()
29982 {
29983         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29984                 skip "Need MDS version at least 2.12.53"
29985
29986         local SAVE_UMASK=$(umask)
29987         local dir=$DIR/$tdir
29988         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29989
29990         mkdir -p $dir
29991         umask 0000
29992         mkdir -m03777 $dir/testdir
29993         ls -dn $dir/testdir
29994         # Need to remove trailing '.' when SELinux is enabled
29995         local dirperms=$(ls -dn $dir/testdir |
29996                          awk '{ sub(/\.$/, "", $1); print $1}')
29997         [ $dirperms == "drwxrwsrwt" ] ||
29998                 error "incorrect perms on $dir/testdir"
29999
30000         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
30001                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
30002         ls -n $dir/testdir/testfile
30003         local fileperms=$(ls -n $dir/testdir/testfile |
30004                           awk '{ sub(/\.$/, "", $1); print $1}')
30005         [ $fileperms == "-rwxr-xr-x" ] ||
30006                 error "incorrect perms on $dir/testdir/testfile"
30007
30008         umask $SAVE_UMASK
30009 }
30010 run_test 420 "clear SGID bit on non-directories for non-members"
30011
30012 test_421a() {
30013         local cnt
30014         local fid1
30015         local fid2
30016
30017         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30018                 skip "Need MDS version at least 2.12.54"
30019
30020         test_mkdir $DIR/$tdir
30021         createmany -o $DIR/$tdir/f 3
30022         cnt=$(ls -1 $DIR/$tdir | wc -l)
30023         [ $cnt != 3 ] && error "unexpected #files: $cnt"
30024
30025         fid1=$(lfs path2fid $DIR/$tdir/f1)
30026         fid2=$(lfs path2fid $DIR/$tdir/f2)
30027         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
30028
30029         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
30030         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
30031
30032         cnt=$(ls -1 $DIR/$tdir | wc -l)
30033         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
30034
30035         rm -f $DIR/$tdir/f3 || error "can't remove f3"
30036         createmany -o $DIR/$tdir/f 3
30037         cnt=$(ls -1 $DIR/$tdir | wc -l)
30038         [ $cnt != 3 ] && error "unexpected #files: $cnt"
30039
30040         fid1=$(lfs path2fid $DIR/$tdir/f1)
30041         fid2=$(lfs path2fid $DIR/$tdir/f2)
30042         echo "remove using fsname $FSNAME"
30043         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
30044
30045         cnt=$(ls -1 $DIR/$tdir | wc -l)
30046         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
30047 }
30048 run_test 421a "simple rm by fid"
30049
30050 test_421b() {
30051         local cnt
30052         local FID1
30053         local FID2
30054
30055         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30056                 skip "Need MDS version at least 2.12.54"
30057
30058         test_mkdir $DIR/$tdir
30059         createmany -o $DIR/$tdir/f 3
30060         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
30061         MULTIPID=$!
30062
30063         FID1=$(lfs path2fid $DIR/$tdir/f1)
30064         FID2=$(lfs path2fid $DIR/$tdir/f2)
30065         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
30066
30067         kill -USR1 $MULTIPID
30068         wait
30069
30070         cnt=$(ls $DIR/$tdir | wc -l)
30071         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
30072 }
30073 run_test 421b "rm by fid on open file"
30074
30075 test_421c() {
30076         local cnt
30077         local FIDS
30078
30079         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30080                 skip "Need MDS version at least 2.12.54"
30081
30082         test_mkdir $DIR/$tdir
30083         createmany -o $DIR/$tdir/f 3
30084         touch $DIR/$tdir/$tfile
30085         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
30086         cnt=$(ls -1 $DIR/$tdir | wc -l)
30087         [ $cnt != 184 ] && error "unexpected #files: $cnt"
30088
30089         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
30090         $LFS rmfid $DIR $FID1 || error "rmfid failed"
30091
30092         cnt=$(ls $DIR/$tdir | wc -l)
30093         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
30094 }
30095 run_test 421c "rm by fid against hardlinked files"
30096
30097 test_421d() {
30098         local cnt
30099         local FIDS
30100
30101         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30102                 skip "Need MDS version at least 2.12.54"
30103
30104         test_mkdir $DIR/$tdir
30105         createmany -o $DIR/$tdir/f 4097
30106         cnt=$(ls -1 $DIR/$tdir | wc -l)
30107         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
30108
30109         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
30110         $LFS rmfid $DIR $FIDS || error "rmfid failed"
30111
30112         cnt=$(ls $DIR/$tdir | wc -l)
30113         rm -rf $DIR/$tdir
30114         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30115 }
30116 run_test 421d "rmfid en masse"
30117
30118 test_421e() {
30119         local cnt
30120         local FID
30121
30122         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30123         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30124                 skip "Need MDS version at least 2.12.54"
30125
30126         mkdir -p $DIR/$tdir
30127         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30128         createmany -o $DIR/$tdir/striped_dir/f 512
30129         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30130         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30131
30132         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30133                 sed "s/[/][^:]*://g")
30134         $LFS rmfid $DIR $FIDS || error "rmfid failed"
30135
30136         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30137         rm -rf $DIR/$tdir
30138         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30139 }
30140 run_test 421e "rmfid in DNE"
30141
30142 test_421f() {
30143         local cnt
30144         local FID
30145
30146         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30147                 skip "Need MDS version at least 2.12.54"
30148
30149         test_mkdir $DIR/$tdir
30150         touch $DIR/$tdir/f
30151         cnt=$(ls -1 $DIR/$tdir | wc -l)
30152         [ $cnt != 1 ] && error "unexpected #files: $cnt"
30153
30154         FID=$(lfs path2fid $DIR/$tdir/f)
30155         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
30156         # rmfid should fail
30157         cnt=$(ls -1 $DIR/$tdir | wc -l)
30158         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
30159
30160         chmod a+rw $DIR/$tdir
30161         ls -la $DIR/$tdir
30162         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
30163         # rmfid should fail
30164         cnt=$(ls -1 $DIR/$tdir | wc -l)
30165         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
30166
30167         rm -f $DIR/$tdir/f
30168         $RUNAS touch $DIR/$tdir/f
30169         FID=$(lfs path2fid $DIR/$tdir/f)
30170         echo "rmfid as root"
30171         $LFS rmfid $DIR $FID || error "rmfid as root failed"
30172         cnt=$(ls -1 $DIR/$tdir | wc -l)
30173         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
30174
30175         rm -f $DIR/$tdir/f
30176         $RUNAS touch $DIR/$tdir/f
30177         cnt=$(ls -1 $DIR/$tdir | wc -l)
30178         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
30179         FID=$(lfs path2fid $DIR/$tdir/f)
30180         # rmfid w/o user_fid2path mount option should fail
30181         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
30182         cnt=$(ls -1 $DIR/$tdir | wc -l)
30183         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
30184
30185         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
30186         stack_trap "rmdir $tmpdir"
30187         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
30188                 error "failed to mount client'"
30189         stack_trap "umount_client $tmpdir"
30190
30191         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
30192         # rmfid should succeed
30193         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
30194         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
30195
30196         # rmfid shouldn't allow to remove files due to dir's permission
30197         chmod a+rwx $tmpdir/$tdir
30198         touch $tmpdir/$tdir/f
30199         ls -la $tmpdir/$tdir
30200         FID=$(lfs path2fid $tmpdir/$tdir/f)
30201         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
30202         return 0
30203 }
30204 run_test 421f "rmfid checks permissions"
30205
30206 test_421g() {
30207         local cnt
30208         local FIDS
30209
30210         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30211         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30212                 skip "Need MDS version at least 2.12.54"
30213
30214         mkdir -p $DIR/$tdir
30215         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30216         createmany -o $DIR/$tdir/striped_dir/f 512
30217         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30218         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30219
30220         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30221                 sed "s/[/][^:]*://g")
30222
30223         rm -f $DIR/$tdir/striped_dir/f1*
30224         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30225         removed=$((512 - cnt))
30226
30227         # few files have been just removed, so we expect
30228         # rmfid to fail on their fids
30229         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30230         [ $removed != $errors ] && error "$errors != $removed"
30231
30232         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30233         rm -rf $DIR/$tdir
30234         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30235 }
30236 run_test 421g "rmfid to return errors properly"
30237
30238 test_421h() {
30239         local mount_other
30240         local mount_ret
30241         local rmfid_ret
30242         local old_fid
30243         local fidA
30244         local fidB
30245         local fidC
30246         local fidD
30247
30248         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30249                 skip "Need MDS version at least 2.15.53"
30250
30251         test_mkdir $DIR/$tdir
30252         test_mkdir $DIR/$tdir/subdir
30253         touch $DIR/$tdir/subdir/file0
30254         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30255         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30256         rm -f $DIR/$tdir/subdir/file0
30257         touch $DIR/$tdir/subdir/fileA
30258         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30259         echo File $DIR/$tdir/subdir/fileA FID $fidA
30260         touch $DIR/$tdir/subdir/fileB
30261         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30262         echo File $DIR/$tdir/subdir/fileB FID $fidB
30263         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30264         touch $DIR/$tdir/subdir/fileC
30265         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30266         echo File $DIR/$tdir/subdir/fileC FID $fidC
30267         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30268         touch $DIR/$tdir/fileD
30269         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30270         echo File $DIR/$tdir/fileD FID $fidD
30271
30272         # mount another client mount point with subdirectory mount
30273         export FILESET=/$tdir/subdir
30274         mount_other=${MOUNT}_other
30275         mount_client $mount_other ${MOUNT_OPTS}
30276         mount_ret=$?
30277         export FILESET=""
30278         (( mount_ret == 0 )) || error "mount $mount_other failed"
30279
30280         echo Removing FIDs:
30281         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30282         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30283         rmfid_ret=$?
30284
30285         umount_client $mount_other || error "umount $mount_other failed"
30286
30287         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30288
30289         # fileA should have been deleted
30290         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30291
30292         # fileB should have been deleted
30293         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30294
30295         # fileC should not have been deleted, fid also exists outside of fileset
30296         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30297
30298         # fileD should not have been deleted, it exists outside of fileset
30299         stat $DIR/$tdir/fileD || error "fileD deleted"
30300 }
30301 run_test 421h "rmfid with fileset mount"
30302
30303 test_422() {
30304         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30305         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30306         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30307         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30308         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30309
30310         local amc=$(at_max_get client)
30311         local amo=$(at_max_get mds1)
30312         local timeout=`lctl get_param -n timeout`
30313
30314         at_max_set 0 client
30315         at_max_set 0 mds1
30316
30317 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30318         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30319                         fail_val=$(((2*timeout + 10)*1000))
30320         touch $DIR/$tdir/d3/file &
30321         sleep 2
30322 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30323         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30324                         fail_val=$((2*timeout + 5))
30325         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30326         local pid=$!
30327         sleep 1
30328         kill -9 $pid
30329         sleep $((2 * timeout))
30330         echo kill $pid
30331         kill -9 $pid
30332         lctl mark touch
30333         touch $DIR/$tdir/d2/file3
30334         touch $DIR/$tdir/d2/file4
30335         touch $DIR/$tdir/d2/file5
30336
30337         wait
30338         at_max_set $amc client
30339         at_max_set $amo mds1
30340
30341         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30342         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30343                 error "Watchdog is always throttled"
30344 }
30345 run_test 422 "kill a process with RPC in progress"
30346
30347 stat_test() {
30348     df -h $MOUNT &
30349     df -h $MOUNT &
30350     df -h $MOUNT &
30351     df -h $MOUNT &
30352     df -h $MOUNT &
30353     df -h $MOUNT &
30354 }
30355
30356 test_423() {
30357     local _stats
30358     # ensure statfs cache is expired
30359     sleep 2;
30360
30361     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30362     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30363
30364     return 0
30365 }
30366 run_test 423 "statfs should return a right data"
30367
30368 test_424() {
30369 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30370         $LCTL set_param fail_loc=0x80000522
30371         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30372         rm -f $DIR/$tfile
30373 }
30374 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30375
30376 test_425() {
30377         test_mkdir -c -1 $DIR/$tdir
30378         $LFS setstripe -c -1 $DIR/$tdir
30379
30380         lru_resize_disable "" 100
30381         stack_trap "lru_resize_enable" EXIT
30382
30383         sleep 5
30384
30385         for i in $(seq $((MDSCOUNT * 125))); do
30386                 local t=$DIR/$tdir/$tfile_$i
30387
30388                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30389                         error_noexit "Create file $t"
30390         done
30391         stack_trap "rm -rf $DIR/$tdir" EXIT
30392
30393         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30394                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30395                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30396
30397                 [ $lock_count -le $lru_size ] ||
30398                         error "osc lock count $lock_count > lru size $lru_size"
30399         done
30400
30401         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30402                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30403                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30404
30405                 [ $lock_count -le $lru_size ] ||
30406                         error "mdc lock count $lock_count > lru size $lru_size"
30407         done
30408 }
30409 run_test 425 "lock count should not exceed lru size"
30410
30411 test_426() {
30412         splice-test -r $DIR/$tfile
30413         splice-test -rd $DIR/$tfile
30414         splice-test $DIR/$tfile
30415         splice-test -d $DIR/$tfile
30416 }
30417 run_test 426 "splice test on Lustre"
30418
30419 test_427() {
30420         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30421         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30422                 skip "Need MDS version at least 2.12.4"
30423         local log
30424
30425         mkdir $DIR/$tdir
30426         mkdir $DIR/$tdir/1
30427         mkdir $DIR/$tdir/2
30428         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30429         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30430
30431         $LFS getdirstripe $DIR/$tdir/1/dir
30432
30433         #first setfattr for creating updatelog
30434         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30435
30436 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30437         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30438         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30439         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30440
30441         sleep 2
30442         fail mds2
30443         wait_recovery_complete mds2 $((2*TIMEOUT))
30444
30445         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30446         echo $log | grep "get update log failed" &&
30447                 error "update log corruption is detected" || true
30448 }
30449 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30450
30451 test_428() {
30452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30453         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30454                               awk '/^max_cached_mb/ { print $2 }')
30455         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30456
30457         $LCTL set_param -n llite.*.max_cached_mb=64
30458
30459         mkdir $DIR/$tdir
30460         $LFS setstripe -c 1 $DIR/$tdir
30461         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30462         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30463         #test write
30464         for f in $(seq 4); do
30465                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30466         done
30467         wait
30468
30469         cancel_lru_locks osc
30470         # Test read
30471         for f in $(seq 4); do
30472                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30473         done
30474         wait
30475 }
30476 run_test 428 "large block size IO should not hang"
30477
30478 test_429() { # LU-7915 / LU-10948
30479         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30480         local testfile=$DIR/$tfile
30481         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30482         local new_flag=1
30483         local first_rpc
30484         local second_rpc
30485         local third_rpc
30486
30487         $LCTL get_param $ll_opencache_threshold_count ||
30488                 skip "client does not have opencache parameter"
30489
30490         set_opencache $new_flag
30491         stack_trap "restore_opencache"
30492         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30493                 error "enable opencache failed"
30494         touch $testfile
30495         # drop MDC DLM locks
30496         cancel_lru_locks mdc
30497         # clear MDC RPC stats counters
30498         $LCTL set_param $mdc_rpcstats=clear
30499
30500         # According to the current implementation, we need to run 3 times
30501         # open & close file to verify if opencache is enabled correctly.
30502         # 1st, RPCs are sent for lookup/open and open handle is released on
30503         #      close finally.
30504         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30505         #      so open handle won't be released thereafter.
30506         # 3rd, No RPC is sent out.
30507         $MULTIOP $testfile oc || error "multiop failed"
30508         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30509         echo "1st: $first_rpc RPCs in flight"
30510
30511         $MULTIOP $testfile oc || error "multiop failed"
30512         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30513         echo "2nd: $second_rpc RPCs in flight"
30514
30515         $MULTIOP $testfile oc || error "multiop failed"
30516         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30517         echo "3rd: $third_rpc RPCs in flight"
30518
30519         #verify no MDC RPC is sent
30520         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30521 }
30522 run_test 429 "verify if opencache flag on client side does work"
30523
30524 lseek_test_430() {
30525         local offset
30526         local file=$1
30527
30528         # data at [200K, 400K)
30529         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30530                 error "256K->512K dd fails"
30531         # data at [2M, 3M)
30532         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30533                 error "2M->3M dd fails"
30534         # data at [4M, 5M)
30535         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30536                 error "4M->5M dd fails"
30537         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30538         # start at first component hole #1
30539         printf "Seeking hole from 1000 ... "
30540         offset=$(lseek_test -l 1000 $file)
30541         echo $offset
30542         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30543         printf "Seeking data from 1000 ... "
30544         offset=$(lseek_test -d 1000 $file)
30545         echo $offset
30546         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30547
30548         # start at first component data block
30549         printf "Seeking hole from 300000 ... "
30550         offset=$(lseek_test -l 300000 $file)
30551         echo $offset
30552         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30553         printf "Seeking data from 300000 ... "
30554         offset=$(lseek_test -d 300000 $file)
30555         echo $offset
30556         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30557
30558         # start at the first component but beyond end of object size
30559         printf "Seeking hole from 1000000 ... "
30560         offset=$(lseek_test -l 1000000 $file)
30561         echo $offset
30562         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30563         printf "Seeking data from 1000000 ... "
30564         offset=$(lseek_test -d 1000000 $file)
30565         echo $offset
30566         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30567
30568         # start at second component stripe 2 (empty file)
30569         printf "Seeking hole from 1500000 ... "
30570         offset=$(lseek_test -l 1500000 $file)
30571         echo $offset
30572         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30573         printf "Seeking data from 1500000 ... "
30574         offset=$(lseek_test -d 1500000 $file)
30575         echo $offset
30576         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30577
30578         # start at second component stripe 1 (all data)
30579         printf "Seeking hole from 3000000 ... "
30580         offset=$(lseek_test -l 3000000 $file)
30581         echo $offset
30582         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30583         printf "Seeking data from 3000000 ... "
30584         offset=$(lseek_test -d 3000000 $file)
30585         echo $offset
30586         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30587
30588         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30589                 error "2nd dd fails"
30590         echo "Add data block at 640K...1280K"
30591
30592         # start at before new data block, in hole
30593         printf "Seeking hole from 600000 ... "
30594         offset=$(lseek_test -l 600000 $file)
30595         echo $offset
30596         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30597         printf "Seeking data from 600000 ... "
30598         offset=$(lseek_test -d 600000 $file)
30599         echo $offset
30600         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30601
30602         # start at the first component new data block
30603         printf "Seeking hole from 1000000 ... "
30604         offset=$(lseek_test -l 1000000 $file)
30605         echo $offset
30606         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30607         printf "Seeking data from 1000000 ... "
30608         offset=$(lseek_test -d 1000000 $file)
30609         echo $offset
30610         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30611
30612         # start at second component stripe 2, new data
30613         printf "Seeking hole from 1200000 ... "
30614         offset=$(lseek_test -l 1200000 $file)
30615         echo $offset
30616         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30617         printf "Seeking data from 1200000 ... "
30618         offset=$(lseek_test -d 1200000 $file)
30619         echo $offset
30620         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30621
30622         # start beyond file end
30623         printf "Using offset > filesize ... "
30624         lseek_test -l 4000000 $file && error "lseek should fail"
30625         printf "Using offset > filesize ... "
30626         lseek_test -d 4000000 $file && error "lseek should fail"
30627
30628         printf "Done\n\n"
30629 }
30630
30631 test_430a() {
30632         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30633                 skip "MDT does not support SEEK_HOLE"
30634
30635         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30636                 skip "OST does not support SEEK_HOLE"
30637
30638         local file=$DIR/$tdir/$tfile
30639
30640         mkdir -p $DIR/$tdir
30641
30642         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30643         # OST stripe #1 will have continuous data at [1M, 3M)
30644         # OST stripe #2 is empty
30645         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30646         lseek_test_430 $file
30647         rm $file
30648         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30649         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30650         lseek_test_430 $file
30651         rm $file
30652         $LFS setstripe -c2 -S 512K $file
30653         echo "Two stripes, stripe size 512K"
30654         lseek_test_430 $file
30655         rm $file
30656         # FLR with stale mirror
30657         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30658                        -N -c2 -S 1M $file
30659         echo "Mirrored file:"
30660         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30661         echo "Plain 2 stripes 1M"
30662         lseek_test_430 $file
30663         rm $file
30664 }
30665 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30666
30667 test_430b() {
30668         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30669                 skip "OST does not support SEEK_HOLE"
30670
30671         local offset
30672         local file=$DIR/$tdir/$tfile
30673
30674         mkdir -p $DIR/$tdir
30675         # Empty layout lseek should fail
30676         $MCREATE $file
30677         # seek from 0
30678         printf "Seeking hole from 0 ... "
30679         lseek_test -l 0 $file && error "lseek should fail"
30680         printf "Seeking data from 0 ... "
30681         lseek_test -d 0 $file && error "lseek should fail"
30682         rm $file
30683
30684         # 1M-hole file
30685         $LFS setstripe -E 1M -c2 -E eof $file
30686         $TRUNCATE $file 1048576
30687         printf "Seeking hole from 1000000 ... "
30688         offset=$(lseek_test -l 1000000 $file)
30689         echo $offset
30690         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30691         printf "Seeking data from 1000000 ... "
30692         lseek_test -d 1000000 $file && error "lseek should fail"
30693         rm $file
30694
30695         # full component followed by non-inited one
30696         $LFS setstripe -E 1M -c2 -E eof $file
30697         dd if=/dev/urandom of=$file bs=1M count=1
30698         printf "Seeking hole from 1000000 ... "
30699         offset=$(lseek_test -l 1000000 $file)
30700         echo $offset
30701         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30702         printf "Seeking hole from 1048576 ... "
30703         lseek_test -l 1048576 $file && error "lseek should fail"
30704         # init second component and truncate back
30705         echo "123" >> $file
30706         $TRUNCATE $file 1048576
30707         printf "Seeking hole from 1000000 ... "
30708         offset=$(lseek_test -l 1000000 $file)
30709         echo $offset
30710         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30711         printf "Seeking hole from 1048576 ... "
30712         lseek_test -l 1048576 $file && error "lseek should fail"
30713         # boundary checks for big values
30714         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30715         offset=$(lseek_test -d 0 $file.10g)
30716         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30717         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30718         offset=$(lseek_test -d 0 $file.100g)
30719         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30720         return 0
30721 }
30722 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30723
30724 test_430c() {
30725         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30726                 skip "OST does not support SEEK_HOLE"
30727
30728         local file=$DIR/$tdir/$tfile
30729         local start
30730
30731         mkdir -p $DIR/$tdir
30732         stack_trap "rm -f $file $file.tmp"
30733         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30734
30735         # cp version 8.33+ prefers lseek over fiemap
30736         local ver=$(cp --version | awk '{ print $4; exit; }')
30737
30738         echo "cp $ver installed"
30739         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30740                 start=$SECONDS
30741                 time cp -v $file $file.tmp || error "cp $file failed"
30742                 (( SECONDS - start < 5 )) || {
30743                         strace cp $file $file.tmp |&
30744                                 grep -E "open|read|seek|FIEMAP" |
30745                                 grep -A 100 $file
30746                         error "cp: too long runtime $((SECONDS - start))"
30747                 }
30748         else
30749                 echo "cp test skipped due to $ver < 8.33"
30750         fi
30751
30752         # tar version 1.29+ supports SEEK_HOLE/DATA
30753         ver=$(tar --version | awk '{ print $4; exit; }')
30754         echo "tar $ver installed"
30755         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30756                 start=$SECONDS
30757                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30758                 (( SECONDS - start < 5 )) || {
30759                         strace tar cf $file.tmp --sparse $file |&
30760                                 grep -E "open|read|seek|FIEMAP" |
30761                                 grep -A 100 $file
30762                         error "tar: too long runtime $((SECONDS - start))"
30763                 }
30764         else
30765                 echo "tar test skipped due to $ver < 1.29"
30766         fi
30767 }
30768 run_test 430c "lseek: external tools check"
30769
30770 test_431() { # LU-14187
30771         local file=$DIR/$tdir/$tfile
30772
30773         mkdir -p $DIR/$tdir
30774         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30775         dd if=/dev/urandom of=$file bs=4k count=1
30776         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30777         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30778         #define OBD_FAIL_OST_RESTART_IO 0x251
30779         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30780         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30781         cp $file $file.0
30782         cancel_lru_locks
30783         sync_all_data
30784         echo 3 > /proc/sys/vm/drop_caches
30785         diff  $file $file.0 || error "data diff"
30786 }
30787 run_test 431 "Restart transaction for IO"
30788
30789 cleanup_test_432() {
30790         do_facet mgs $LCTL nodemap_activate 0
30791         wait_nm_sync active
30792 }
30793
30794 test_432() {
30795         local tmpdir=$TMP/dir432
30796
30797         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30798                 skip "Need MDS version at least 2.14.52"
30799
30800         stack_trap cleanup_test_432 EXIT
30801         mkdir $DIR/$tdir
30802         mkdir $tmpdir
30803
30804         do_facet mgs $LCTL nodemap_activate 1
30805         wait_nm_sync active
30806         do_facet mgs $LCTL nodemap_modify --name default \
30807                 --property admin --value 1
30808         do_facet mgs $LCTL nodemap_modify --name default \
30809                 --property trusted --value 1
30810         cancel_lru_locks mdc
30811         wait_nm_sync default admin_nodemap
30812         wait_nm_sync default trusted_nodemap
30813
30814         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30815                grep -ci "Operation not permitted") -ne 0 ]; then
30816                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30817         fi
30818 }
30819 run_test 432 "mv dir from outside Lustre"
30820
30821 test_433() {
30822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30823
30824         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30825                 skip "inode cache not supported"
30826
30827         $LCTL set_param llite.*.inode_cache=0
30828         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30829
30830         local count=256
30831         local before
30832         local after
30833
30834         cancel_lru_locks mdc
30835         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30836         createmany -m $DIR/$tdir/f $count
30837         createmany -d $DIR/$tdir/d $count
30838         ls -l $DIR/$tdir > /dev/null
30839         stack_trap "rm -rf $DIR/$tdir"
30840
30841         before=$(num_objects)
30842         cancel_lru_locks mdc
30843         after=$(num_objects)
30844
30845         # sometimes even @before is less than 2 * count
30846         while (( before - after < count )); do
30847                 sleep 1
30848                 after=$(num_objects)
30849                 wait=$((wait + 1))
30850                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30851                 if (( wait > 60 )); then
30852                         error "inode slab grew from $before to $after"
30853                 fi
30854         done
30855
30856         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30857 }
30858 run_test 433 "ldlm lock cancel releases dentries and inodes"
30859
30860 test_434() {
30861         local file
30862         local getxattr_count
30863         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30864         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30865
30866         [[ $(getenforce) == "Disabled" ]] ||
30867                 skip "lsm selinux module have to be disabled for this test"
30868
30869         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30870                 error "fail to create $DIR/$tdir/ on MDT0000"
30871
30872         touch $DIR/$tdir/$tfile-{001..100}
30873
30874         # disable the xattr cache
30875         save_lustre_params client "llite.*.xattr_cache" > $p
30876         lctl set_param llite.*.xattr_cache=0
30877         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30878
30879         # clear clients mdc stats
30880         clear_stats $mdc_stat_param ||
30881                 error "fail to clear stats on mdc MDT0000"
30882
30883         for file in $DIR/$tdir/$tfile-{001..100}; do
30884                 getfattr -n security.selinux $file |&
30885                         grep -q "Operation not supported" ||
30886                         error "getxattr on security.selinux should return EOPNOTSUPP"
30887         done
30888
30889         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30890         (( getxattr_count < 100 )) ||
30891                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30892 }
30893 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30894
30895 test_440() {
30896         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30897                 source $LUSTRE/scripts/bash-completion/lustre
30898         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30899                 source /usr/share/bash-completion/completions/lustre
30900         else
30901                 skip "bash completion scripts not found"
30902         fi
30903
30904         local lctl_completions
30905         local lfs_completions
30906
30907         lctl_completions=$(_lustre_cmds lctl)
30908         if [[ ! $lctl_completions =~ "get_param" ]]; then
30909                 error "lctl bash completion failed"
30910         fi
30911
30912         lfs_completions=$(_lustre_cmds lfs)
30913         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30914                 error "lfs bash completion failed"
30915         fi
30916 }
30917 run_test 440 "bash completion for lfs, lctl"
30918
30919 test_442() {
30920         local pid1
30921         local pid2
30922         mkdir -p $DIR/$tdir
30923         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30924         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30925         sleep 1
30926         touch $DIR/$tdir/$tfile.2
30927         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30928         $LCTL set_param fail_loc=0x1430
30929         kill -USR1 $pid1
30930         sleep 1
30931         kill -USR1 $pid2
30932         wait
30933 }
30934 run_test 442 "truncate vs read/write should not panic"
30935
30936 test_460d() {
30937         verify_yaml_available || skip_env "YAML verification not installed"
30938         $LCTL get_param -n sptlrpc.page_pools
30939         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30940                 error "The output of encrypt_page_pools is not an valid YAML"
30941 }
30942 run_test 460d "Check encrypt pools output"
30943
30944 prep_801() {
30945         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30946         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30947                 skip "Need server version at least 2.9.55"
30948
30949         start_full_debug_logging
30950 }
30951
30952 post_801() {
30953         stop_full_debug_logging
30954 }
30955
30956 barrier_stat() {
30957         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30958                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30959                            awk '/The barrier for/ { print $7 }')
30960                 echo $st
30961         else
30962                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30963                 echo \'$st\'
30964         fi
30965 }
30966
30967 barrier_expired() {
30968         local expired
30969
30970         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30971                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30972                           awk '/will be expired/ { print $7 }')
30973         else
30974                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30975         fi
30976
30977         echo $expired
30978 }
30979
30980 test_801a() {
30981         prep_801
30982
30983         echo "Start barrier_freeze at: $(date)"
30984         #define OBD_FAIL_BARRIER_DELAY          0x2202
30985         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30986         # Do not reduce barrier time - See LU-11873
30987         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30988
30989         sleep 2
30990         local b_status=$(barrier_stat)
30991         echo "Got barrier status at: $(date)"
30992         [ "$b_status" = "'freezing_p1'" ] ||
30993                 error "(1) unexpected barrier status $b_status"
30994
30995         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30996         wait
30997         b_status=$(barrier_stat)
30998         [ "$b_status" = "'frozen'" ] ||
30999                 error "(2) unexpected barrier status $b_status"
31000
31001         local expired=$(barrier_expired)
31002         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
31003         sleep $((expired + 3))
31004
31005         b_status=$(barrier_stat)
31006         [ "$b_status" = "'expired'" ] ||
31007                 error "(3) unexpected barrier status $b_status"
31008
31009         # Do not reduce barrier time - See LU-11873
31010         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
31011                 error "(4) fail to freeze barrier"
31012
31013         b_status=$(barrier_stat)
31014         [ "$b_status" = "'frozen'" ] ||
31015                 error "(5) unexpected barrier status $b_status"
31016
31017         echo "Start barrier_thaw at: $(date)"
31018         #define OBD_FAIL_BARRIER_DELAY          0x2202
31019         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
31020         do_facet mgs $LCTL barrier_thaw $FSNAME &
31021
31022         sleep 2
31023         b_status=$(barrier_stat)
31024         echo "Got barrier status at: $(date)"
31025         [ "$b_status" = "'thawing'" ] ||
31026                 error "(6) unexpected barrier status $b_status"
31027
31028         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
31029         wait
31030         b_status=$(barrier_stat)
31031         [ "$b_status" = "'thawed'" ] ||
31032                 error "(7) unexpected barrier status $b_status"
31033
31034         #define OBD_FAIL_BARRIER_FAILURE        0x2203
31035         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
31036         do_facet mgs $LCTL barrier_freeze $FSNAME
31037
31038         b_status=$(barrier_stat)
31039         [ "$b_status" = "'failed'" ] ||
31040                 error "(8) unexpected barrier status $b_status"
31041
31042         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
31043         do_facet mgs $LCTL barrier_thaw $FSNAME
31044
31045         post_801
31046 }
31047 run_test 801a "write barrier user interfaces and stat machine"
31048
31049 test_801b() {
31050         prep_801
31051
31052         mkdir $DIR/$tdir || error "(1) fail to mkdir"
31053         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
31054         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
31055         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
31056         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
31057
31058         cancel_lru_locks mdc
31059
31060         # 180 seconds should be long enough
31061         do_facet mgs $LCTL barrier_freeze $FSNAME 180
31062
31063         local b_status=$(barrier_stat)
31064         [ "$b_status" = "'frozen'" ] ||
31065                 error "(6) unexpected barrier status $b_status"
31066
31067         mkdir $DIR/$tdir/d0/d10 &
31068         mkdir_pid=$!
31069
31070         touch $DIR/$tdir/d1/f13 &
31071         touch_pid=$!
31072
31073         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
31074         ln_pid=$!
31075
31076         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
31077         mv_pid=$!
31078
31079         rm -f $DIR/$tdir/d4/f12 &
31080         rm_pid=$!
31081
31082         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
31083
31084         # To guarantee taht the 'stat' is not blocked
31085         b_status=$(barrier_stat)
31086         [ "$b_status" = "'frozen'" ] ||
31087                 error "(8) unexpected barrier status $b_status"
31088
31089         # let above commands to run at background
31090         sleep 5
31091
31092         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
31093         ps -p $touch_pid || error "(10) touch should be blocked"
31094         ps -p $ln_pid || error "(11) link should be blocked"
31095         ps -p $mv_pid || error "(12) rename should be blocked"
31096         ps -p $rm_pid || error "(13) unlink should be blocked"
31097
31098         b_status=$(barrier_stat)
31099         [ "$b_status" = "'frozen'" ] ||
31100                 error "(14) unexpected barrier status $b_status"
31101
31102         do_facet mgs $LCTL barrier_thaw $FSNAME
31103         b_status=$(barrier_stat)
31104         [ "$b_status" = "'thawed'" ] ||
31105                 error "(15) unexpected barrier status $b_status"
31106
31107         wait $mkdir_pid || error "(16) mkdir should succeed"
31108         wait $touch_pid || error "(17) touch should succeed"
31109         wait $ln_pid || error "(18) link should succeed"
31110         wait $mv_pid || error "(19) rename should succeed"
31111         wait $rm_pid || error "(20) unlink should succeed"
31112
31113         post_801
31114 }
31115 run_test 801b "modification will be blocked by write barrier"
31116
31117 test_801c() {
31118         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31119
31120         prep_801
31121
31122         stop mds2 || error "(1) Fail to stop mds2"
31123
31124         do_facet mgs $LCTL barrier_freeze $FSNAME 30
31125
31126         local b_status=$(barrier_stat)
31127         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
31128                 do_facet mgs $LCTL barrier_thaw $FSNAME
31129                 error "(2) unexpected barrier status $b_status"
31130         }
31131
31132         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31133                 error "(3) Fail to rescan barrier bitmap"
31134
31135         # Do not reduce barrier time - See LU-11873
31136         do_facet mgs $LCTL barrier_freeze $FSNAME 20
31137
31138         b_status=$(barrier_stat)
31139         [ "$b_status" = "'frozen'" ] ||
31140                 error "(4) unexpected barrier status $b_status"
31141
31142         do_facet mgs $LCTL barrier_thaw $FSNAME
31143         b_status=$(barrier_stat)
31144         [ "$b_status" = "'thawed'" ] ||
31145                 error "(5) unexpected barrier status $b_status"
31146
31147         local devname=$(mdsdevname 2)
31148
31149         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
31150
31151         do_facet mgs $LCTL barrier_rescan $FSNAME ||
31152                 error "(7) Fail to rescan barrier bitmap"
31153
31154         post_801
31155 }
31156 run_test 801c "rescan barrier bitmap"
31157
31158 test_802b() {
31159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31160         remote_mds_nodsh && skip "remote MDS with nodsh"
31161
31162         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
31163                 skip "readonly option not available"
31164
31165         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
31166
31167         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
31168                 error "(2) Fail to copy"
31169
31170         # write back all cached data before setting MDT to readonly
31171         cancel_lru_locks
31172         sync_all_data
31173
31174         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
31175         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
31176
31177         echo "Modify should be refused"
31178         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
31179
31180         echo "Read should be allowed"
31181         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
31182                 error "(7) Read should succeed under ro mode"
31183
31184         # disable readonly
31185         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
31186 }
31187 run_test 802b "be able to set MDTs to readonly"
31188
31189 test_803a() {
31190         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31191         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31192                 skip "MDS needs to be newer than 2.10.54"
31193
31194         mkdir_on_mdt0 $DIR/$tdir
31195         # Create some objects on all MDTs to trigger related logs objects
31196         for idx in $(seq $MDSCOUNT); do
31197                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
31198                         $DIR/$tdir/dir${idx} ||
31199                         error "Fail to create $DIR/$tdir/dir${idx}"
31200         done
31201
31202         wait_delete_completed # ensure old test cleanups are finished
31203         sleep 3
31204         echo "before create:"
31205         $LFS df -i $MOUNT
31206         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31207
31208         for i in {1..10}; do
31209                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31210                         error "Fail to create $DIR/$tdir/foo$i"
31211         done
31212
31213         # sync ZFS-on-MDS to refresh statfs data
31214         wait_zfs_commit mds1
31215         sleep 3
31216         echo "after create:"
31217         $LFS df -i $MOUNT
31218         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31219
31220         # allow for an llog to be cleaned up during the test
31221         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31222                 error "before ($before_used) + 10 > after ($after_used)"
31223
31224         for i in {1..10}; do
31225                 rm -rf $DIR/$tdir/foo$i ||
31226                         error "Fail to remove $DIR/$tdir/foo$i"
31227         done
31228
31229         # sync ZFS-on-MDS to refresh statfs data
31230         wait_zfs_commit mds1
31231         wait_delete_completed
31232         sleep 3 # avoid MDT return cached statfs
31233         echo "after unlink:"
31234         $LFS df -i $MOUNT
31235         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31236
31237         # allow for an llog to be created during the test
31238         [ $after_used -le $((before_used + 1)) ] ||
31239                 error "after ($after_used) > before ($before_used) + 1"
31240 }
31241 run_test 803a "verify agent object for remote object"
31242
31243 test_803b() {
31244         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31245         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31246                 skip "MDS needs to be newer than 2.13.56"
31247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31248
31249         for i in $(seq 0 $((MDSCOUNT - 1))); do
31250                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31251         done
31252
31253         local before=0
31254         local after=0
31255
31256         local tmp
31257
31258         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31259         for i in $(seq 0 $((MDSCOUNT - 1))); do
31260                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31261                         awk '/getattr/ { print $2 }')
31262                 before=$((before + tmp))
31263         done
31264         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31265         for i in $(seq 0 $((MDSCOUNT - 1))); do
31266                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31267                         awk '/getattr/ { print $2 }')
31268                 after=$((after + tmp))
31269         done
31270
31271         [ $before -eq $after ] || error "getattr count $before != $after"
31272 }
31273 run_test 803b "remote object can getattr from cache"
31274
31275 test_804() {
31276         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31277         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31278                 skip "MDS needs to be newer than 2.10.54"
31279         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31280
31281         mkdir -p $DIR/$tdir
31282         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31283                 error "Fail to create $DIR/$tdir/dir0"
31284
31285         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31286         local dev=$(mdsdevname 2)
31287
31288         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31289                 grep ${fid} || error "NOT found agent entry for dir0"
31290
31291         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31292                 error "Fail to create $DIR/$tdir/dir1"
31293
31294         touch $DIR/$tdir/dir1/foo0 ||
31295                 error "Fail to create $DIR/$tdir/dir1/foo0"
31296         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31297         local rc=0
31298
31299         for idx in $(seq $MDSCOUNT); do
31300                 dev=$(mdsdevname $idx)
31301                 do_facet mds${idx} \
31302                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31303                         grep ${fid} && rc=$idx
31304         done
31305
31306         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31307                 error "Fail to rename foo0 to foo1"
31308         if [ $rc -eq 0 ]; then
31309                 for idx in $(seq $MDSCOUNT); do
31310                         dev=$(mdsdevname $idx)
31311                         do_facet mds${idx} \
31312                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31313                         grep ${fid} && rc=$idx
31314                 done
31315         fi
31316
31317         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31318                 error "Fail to rename foo1 to foo2"
31319         if [ $rc -eq 0 ]; then
31320                 for idx in $(seq $MDSCOUNT); do
31321                         dev=$(mdsdevname $idx)
31322                         do_facet mds${idx} \
31323                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31324                         grep ${fid} && rc=$idx
31325                 done
31326         fi
31327
31328         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31329
31330         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31331                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31332         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31333                 error "Fail to rename foo2 to foo0"
31334         unlink $DIR/$tdir/dir1/foo0 ||
31335                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31336         rm -rf $DIR/$tdir/dir0 ||
31337                 error "Fail to rm $DIR/$tdir/dir0"
31338
31339         for idx in $(seq $MDSCOUNT); do
31340                 rc=0
31341
31342                 stop mds${idx}
31343                 dev=$(mdsdevname $idx)
31344                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31345                         rc=$?
31346                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31347                         error "mount mds$idx failed"
31348                 df $MOUNT > /dev/null 2>&1
31349
31350                 # e2fsck should not return error
31351                 [ $rc -eq 0 ] ||
31352                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31353         done
31354 }
31355 run_test 804 "verify agent entry for remote entry"
31356
31357 cleanup_805() {
31358         do_facet $SINGLEMDS zfs set quota=$old $fsset
31359         unlinkmany $DIR/$tdir/f- 1000000
31360         trap 0
31361 }
31362
31363 test_805() {
31364         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31365         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31366         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31367                 skip "netfree not implemented before 0.7"
31368         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31369                 skip "Need MDS version at least 2.10.57"
31370
31371         local fsset
31372         local freekb
31373         local usedkb
31374         local old
31375         local quota
31376         local pref="osd-zfs.$FSNAME-MDT0000."
31377
31378         # limit available space on MDS dataset to meet nospace issue
31379         # quickly. then ZFS 0.7.2 can use reserved space if asked
31380         # properly (using netfree flag in osd_declare_destroy()
31381         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31382         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31383                 gawk '{print $3}')
31384         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31385         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31386         let "usedkb=usedkb-freekb"
31387         let "freekb=freekb/2"
31388         if let "freekb > 5000"; then
31389                 let "freekb=5000"
31390         fi
31391         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31392         trap cleanup_805 EXIT
31393         mkdir_on_mdt0 $DIR/$tdir
31394         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31395                 error "Can't set PFL layout"
31396         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31397         rm -rf $DIR/$tdir || error "not able to remove"
31398         do_facet $SINGLEMDS zfs set quota=$old $fsset
31399         trap 0
31400 }
31401 run_test 805 "ZFS can remove from full fs"
31402
31403 # Size-on-MDS test
31404 check_lsom_data()
31405 {
31406         local file=$1
31407         local expect=$(stat -c %s $file)
31408         local msg=$2
31409
31410         check_lsom_size $1 $expect $msg
31411
31412         local blocks=$($LFS getsom -b $file)
31413         expect=$(stat -c %b $file)
31414         [[ $blocks == $expect ]] ||
31415                 error "$msg $file expected blocks: $expect, got: $blocks"
31416 }
31417
31418 check_lsom_size()
31419 {
31420         local size
31421         local expect=$2
31422         local msg=$3
31423
31424         cancel_lru_locks mdc
31425
31426         size=$($LFS getsom -s $1)
31427         [[ $size == $expect ]] ||
31428                 error "$msg $file expected size: $expect, got: $size"
31429 }
31430
31431 test_806() {
31432         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31433                 skip "Need MDS version at least 2.11.52"
31434
31435         local bs=1048576
31436
31437         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31438
31439         disable_opencache
31440         stack_trap "restore_opencache"
31441
31442         # single-threaded write
31443         echo "Test SOM for single-threaded write"
31444         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31445                 error "write $tfile failed"
31446         check_lsom_size $DIR/$tfile $bs "(0)"
31447         # Test SOM with DIO write (dd truncates to 0)
31448         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 oflag=direct ||
31449                 error "write $tfile failed"
31450         check_lsom_size $DIR/$tfile $bs "(1)"
31451
31452         local num=32
31453         local size=$(($num * $bs))
31454         local offset=0
31455         local i
31456
31457         echo "Test SOM for single client multi-threaded($num) write"
31458         $TRUNCATE $DIR/$tfile 0
31459         for ((i = 0; i < $num; i++)); do
31460                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31461                 local pids[$i]=$!
31462                 offset=$((offset + $bs))
31463         done
31464         for (( i=0; i < $num; i++ )); do
31465                 wait ${pids[$i]}
31466         done
31467         check_lsom_size $DIR/$tfile $size "(2)"
31468
31469         $TRUNCATE $DIR/$tfile 0
31470         for ((i = 0; i < $num; i++)); do
31471                 offset=$((offset - $bs))
31472                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31473                 local pids[$i]=$!
31474         done
31475         for (( i=0; i < $num; i++ )); do
31476                 wait ${pids[$i]}
31477         done
31478         check_lsom_size $DIR/$tfile $size "(3)"
31479
31480         # multi-client writes
31481         num=$(get_node_count ${CLIENTS//,/ })
31482         size=$(($num * $bs))
31483         offset=0
31484         i=0
31485
31486         echo "Test SOM for multi-client ($num) writes"
31487         $TRUNCATE $DIR/$tfile 0
31488         for client in ${CLIENTS//,/ }; do
31489                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31490                 local pids[$i]=$!
31491                 i=$((i + 1))
31492                 offset=$((offset + $bs))
31493         done
31494         for (( i=0; i < $num; i++ )); do
31495                 wait ${pids[$i]}
31496         done
31497         check_lsom_size $DIR/$tfile $offset "(4)"
31498
31499         i=0
31500         $TRUNCATE $DIR/$tfile 0
31501         for client in ${CLIENTS//,/ }; do
31502                 offset=$((offset - $bs))
31503                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31504                 local pids[$i]=$!
31505                 i=$((i + 1))
31506         done
31507         for (( i=0; i < $num; i++ )); do
31508                 wait ${pids[$i]}
31509         done
31510         check_lsom_size $DIR/$tfile $size "(5)"
31511
31512         # verify SOM blocks count
31513         echo "Verify SOM block count"
31514         $TRUNCATE $DIR/$tfile 0
31515         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31516                 error "failed to write file $tfile with fdatasync and fstat"
31517         check_lsom_data $DIR/$tfile "(6)"
31518
31519         $TRUNCATE $DIR/$tfile 0
31520         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31521                 error "failed to write file $tfile with fdatasync"
31522         check_lsom_data $DIR/$tfile "(7)"
31523
31524         $TRUNCATE $DIR/$tfile 0
31525         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31526                 error "failed to write file $tfile with sync IO"
31527         check_lsom_data $DIR/$tfile "(8)"
31528
31529         # verify truncate
31530         echo "Test SOM for truncate"
31531         # use ftruncate to sync blocks on close request
31532         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31533         check_lsom_size $DIR/$tfile 16384 "(9)"
31534         check_lsom_data $DIR/$tfile "(10)"
31535
31536         $TRUNCATE $DIR/$tfile 1234
31537         check_lsom_size $DIR/$tfile 1234 "(11)"
31538         # sync blocks on the MDT
31539         $MULTIOP $DIR/$tfile oc
31540         check_lsom_data $DIR/$tfile "(12)"
31541 }
31542 run_test 806 "Verify Lazy Size on MDS"
31543
31544 test_807() {
31545         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31546         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31547                 skip "Need MDS version at least 2.11.52"
31548
31549         # Registration step
31550         changelog_register || error "changelog_register failed"
31551         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31552         changelog_users $SINGLEMDS | grep -q $cl_user ||
31553                 error "User $cl_user not found in changelog_users"
31554
31555         rm -rf $DIR/$tdir || error "rm $tdir failed"
31556         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31557         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31558         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31559         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31560                 error "truncate $tdir/trunc failed"
31561
31562         local bs=1048576
31563         echo "Test SOM for single-threaded write with fsync"
31564         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31565                 error "write $tfile failed"
31566         sync;sync;sync
31567
31568         # multi-client wirtes
31569         local num=$(get_node_count ${CLIENTS//,/ })
31570         local offset=0
31571         local i=0
31572
31573         echo "Test SOM for multi-client ($num) writes"
31574         touch $DIR/$tfile || error "touch $tfile failed"
31575         $TRUNCATE $DIR/$tfile 0
31576         for client in ${CLIENTS//,/ }; do
31577                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31578                 local pids[$i]=$!
31579                 i=$((i + 1))
31580                 offset=$((offset + $bs))
31581         done
31582         for (( i=0; i < $num; i++ )); do
31583                 wait ${pids[$i]}
31584         done
31585
31586         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31587         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31588         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31589         check_lsom_data $DIR/$tdir/trunc "(0)"
31590         check_lsom_data $DIR/$tdir/single_dd "(1)"
31591         check_lsom_data $DIR/$tfile "(2)"
31592
31593         rm -rf $DIR/$tdir
31594         # Deregistration step
31595         changelog_deregister || error "changelog_deregister failed"
31596 }
31597 run_test 807 "verify LSOM syncing tool"
31598
31599 check_som_nologged()
31600 {
31601         local lines=$($LFS changelog $FSNAME-MDT0000 |
31602                 grep 'x=trusted.som' | wc -l)
31603         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31604 }
31605
31606 test_808() {
31607         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31608                 skip "Need MDS version at least 2.11.55"
31609
31610         # Registration step
31611         changelog_register || error "changelog_register failed"
31612
31613         touch $DIR/$tfile || error "touch $tfile failed"
31614         check_som_nologged
31615
31616         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31617                 error "write $tfile failed"
31618         check_som_nologged
31619
31620         $TRUNCATE $DIR/$tfile 1234
31621         check_som_nologged
31622
31623         $TRUNCATE $DIR/$tfile 1048576
31624         check_som_nologged
31625
31626         # Deregistration step
31627         changelog_deregister || error "changelog_deregister failed"
31628 }
31629 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31630
31631 check_som_nodata()
31632 {
31633         $LFS getsom $1
31634         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31635 }
31636
31637 test_809() {
31638         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31639                 skip "Need MDS version at least 2.11.56"
31640
31641         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31642                 error "failed to create DoM-only file $DIR/$tfile"
31643         touch $DIR/$tfile || error "touch $tfile failed"
31644         check_som_nodata $DIR/$tfile
31645
31646         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31647                 error "write $tfile failed"
31648         check_som_nodata $DIR/$tfile
31649
31650         $TRUNCATE $DIR/$tfile 1234
31651         check_som_nodata $DIR/$tfile
31652
31653         $TRUNCATE $DIR/$tfile 4097
31654         check_som_nodata $DIR/$file
31655 }
31656 run_test 809 "Verify no SOM xattr store for DoM-only files"
31657
31658 test_810() {
31659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31660         $GSS && skip_env "could not run with gss"
31661         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31662                 skip "OST < 2.12.58 doesn't align checksum"
31663
31664         set_checksums 1
31665         stack_trap "set_checksums $ORIG_CSUM" EXIT
31666         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31667
31668         local csum
31669         local before
31670         local after
31671         for csum in $CKSUM_TYPES; do
31672                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31673                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31674                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31675                         eval set -- $i
31676                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31677                         before=$(md5sum $DIR/$tfile)
31678                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31679                         after=$(md5sum $DIR/$tfile)
31680                         [ "$before" == "$after" ] ||
31681                                 error "$csum: $before != $after bs=$1 seek=$2"
31682                 done
31683         done
31684 }
31685 run_test 810 "partial page writes on ZFS (LU-11663)"
31686
31687 test_812a() {
31688         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31689                 skip "OST < 2.12.51 doesn't support this fail_loc"
31690         local old
31691
31692         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31693         $LCTL set_param osc.*.idle_timeout=10
31694         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31695
31696         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31697         # ensure ost1 is connected
31698         stat $DIR/$tfile >/dev/null || error "can't stat"
31699         wait_osc_import_state client ost1 FULL
31700         # no locks, no reqs to let the connection idle
31701         cancel_lru_locks osc
31702
31703         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31704 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31705         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31706         wait_osc_import_state client ost1 CONNECTING
31707         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31708
31709         stat $DIR/$tfile >/dev/null || error "can't stat file"
31710 }
31711 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31712
31713 test_812b() { # LU-12378
31714         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31715                 skip "OST < 2.12.51 doesn't support this fail_loc"
31716         local old
31717
31718         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31719         $LCTL set_param osc.*.idle_timeout=10
31720         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31721
31722         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31723         # ensure ost1 is connected
31724         stat $DIR/$tfile >/dev/null || error "can't stat"
31725         wait_osc_import_state client ost1 FULL
31726         # no locks, no reqs to let the connection idle
31727         cancel_lru_locks osc
31728
31729         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31730 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31731         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31732         wait_osc_import_state client ost1 CONNECTING
31733         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31734
31735         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31736         wait_osc_import_state client ost1 IDLE
31737 }
31738 run_test 812b "do not drop no resend request for idle connect"
31739
31740 test_812c() {
31741         local old
31742
31743         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31744
31745         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31746         $LFS getstripe $DIR/$tfile
31747         $LCTL set_param osc.*.idle_timeout=10
31748         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31749         # ensure ost1 is connected
31750         stat $DIR/$tfile >/dev/null || error "can't stat"
31751         wait_osc_import_state client ost1 FULL
31752         # no locks, no reqs to let the connection idle
31753         cancel_lru_locks osc
31754
31755 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31756         $LCTL set_param fail_loc=0x80000533
31757         sleep 15
31758         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31759 }
31760 run_test 812c "idle import vs lock enqueue race"
31761
31762 test_813() {
31763         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31764         [ -z "$file_heat_sav" ] && skip "no file heat support"
31765
31766         local readsample
31767         local writesample
31768         local readbyte
31769         local writebyte
31770         local readsample1
31771         local writesample1
31772         local readbyte1
31773         local writebyte1
31774
31775         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31776         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31777
31778         $LCTL set_param -n llite.*.file_heat=1
31779         echo "Turn on file heat"
31780         echo "Period second: $period_second, Decay percentage: $decay_pct"
31781
31782         echo "QQQQ" > $DIR/$tfile
31783         echo "QQQQ" > $DIR/$tfile
31784         echo "QQQQ" > $DIR/$tfile
31785         cat $DIR/$tfile > /dev/null
31786         cat $DIR/$tfile > /dev/null
31787         cat $DIR/$tfile > /dev/null
31788         cat $DIR/$tfile > /dev/null
31789
31790         local out=$($LFS heat_get $DIR/$tfile)
31791
31792         $LFS heat_get $DIR/$tfile
31793         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31794         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31795         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31796         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31797
31798         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31799         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31800         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31801         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31802
31803         sleep $((period_second + 3))
31804         echo "Sleep $((period_second + 3)) seconds..."
31805         # The recursion formula to calculate the heat of the file f is as
31806         # follow:
31807         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31808         # Where Hi is the heat value in the period between time points i*I and
31809         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31810         # to the weight of Ci.
31811         out=$($LFS heat_get $DIR/$tfile)
31812         $LFS heat_get $DIR/$tfile
31813         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31814         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31815         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31816         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31817
31818         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31819                 error "read sample ($readsample) is wrong"
31820         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31821                 error "write sample ($writesample) is wrong"
31822         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31823                 error "read bytes ($readbyte) is wrong"
31824         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31825                 error "write bytes ($writebyte) is wrong"
31826
31827         echo "QQQQ" > $DIR/$tfile
31828         echo "QQQQ" > $DIR/$tfile
31829         echo "QQQQ" > $DIR/$tfile
31830         cat $DIR/$tfile > /dev/null
31831         cat $DIR/$tfile > /dev/null
31832         cat $DIR/$tfile > /dev/null
31833         cat $DIR/$tfile > /dev/null
31834
31835         sleep $((period_second + 3))
31836         echo "Sleep $((period_second + 3)) seconds..."
31837
31838         out=$($LFS heat_get $DIR/$tfile)
31839         $LFS heat_get $DIR/$tfile
31840         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31841         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31842         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31843         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31844
31845         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31846                 4 * $decay_pct) / 100") -eq 1 ] ||
31847                 error "read sample ($readsample1) is wrong"
31848         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31849                 3 * $decay_pct) / 100") -eq 1 ] ||
31850                 error "write sample ($writesample1) is wrong"
31851         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31852                 20 * $decay_pct) / 100") -eq 1 ] ||
31853                 error "read bytes ($readbyte1) is wrong"
31854         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31855                 15 * $decay_pct) / 100") -eq 1 ] ||
31856                 error "write bytes ($writebyte1) is wrong"
31857
31858         echo "Turn off file heat for the file $DIR/$tfile"
31859         $LFS heat_set -o $DIR/$tfile
31860
31861         echo "QQQQ" > $DIR/$tfile
31862         echo "QQQQ" > $DIR/$tfile
31863         echo "QQQQ" > $DIR/$tfile
31864         cat $DIR/$tfile > /dev/null
31865         cat $DIR/$tfile > /dev/null
31866         cat $DIR/$tfile > /dev/null
31867         cat $DIR/$tfile > /dev/null
31868
31869         out=$($LFS heat_get $DIR/$tfile)
31870         $LFS heat_get $DIR/$tfile
31871         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31872         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31873         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31874         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31875
31876         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31877         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31878         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31879         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31880
31881         echo "Trun on file heat for the file $DIR/$tfile"
31882         $LFS heat_set -O $DIR/$tfile
31883
31884         echo "QQQQ" > $DIR/$tfile
31885         echo "QQQQ" > $DIR/$tfile
31886         echo "QQQQ" > $DIR/$tfile
31887         cat $DIR/$tfile > /dev/null
31888         cat $DIR/$tfile > /dev/null
31889         cat $DIR/$tfile > /dev/null
31890         cat $DIR/$tfile > /dev/null
31891
31892         out=$($LFS heat_get $DIR/$tfile)
31893         $LFS heat_get $DIR/$tfile
31894         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31895         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31896         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31897         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31898
31899         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31900         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31901         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31902         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31903
31904         $LFS heat_set -c $DIR/$tfile
31905         $LCTL set_param -n llite.*.file_heat=0
31906         echo "Turn off file heat support for the Lustre filesystem"
31907
31908         echo "QQQQ" > $DIR/$tfile
31909         echo "QQQQ" > $DIR/$tfile
31910         echo "QQQQ" > $DIR/$tfile
31911         cat $DIR/$tfile > /dev/null
31912         cat $DIR/$tfile > /dev/null
31913         cat $DIR/$tfile > /dev/null
31914         cat $DIR/$tfile > /dev/null
31915
31916         out=$($LFS heat_get $DIR/$tfile)
31917         $LFS heat_get $DIR/$tfile
31918         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31919         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31920         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31921         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31922
31923         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31924         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31925         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31926         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31927
31928         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31929         rm -f $DIR/$tfile
31930 }
31931 run_test 813 "File heat verfication"
31932
31933 test_814()
31934 {
31935         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31936         echo -n y >> $DIR/$tfile
31937         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31938         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31939 }
31940 run_test 814 "sparse cp works as expected (LU-12361)"
31941
31942 test_815()
31943 {
31944         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31945         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31946 }
31947 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31948
31949 test_816() {
31950         local ost1_imp=$(get_osc_import_name client ost1)
31951         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31952                          cut -d'.' -f2)
31953         local old
31954
31955         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31956         $LCTL set_param osc.*.idle_timeout=10
31957         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31958
31959         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31960         # ensure ost1 is connected
31961
31962         stat $DIR/$tfile >/dev/null || error "can't stat"
31963         wait_osc_import_state client ost1 FULL
31964         # no locks, no reqs to let the connection idle
31965         cancel_lru_locks osc
31966         lru_resize_disable osc
31967         local before
31968         local now
31969         before=$($LCTL get_param -n \
31970                  ldlm.namespaces.$imp_name.lru_size)
31971
31972         wait_osc_import_state client ost1 IDLE
31973         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31974         now=$($LCTL get_param -n \
31975               ldlm.namespaces.$imp_name.lru_size)
31976         [ $before == $now ] || error "lru_size changed $before != $now"
31977 }
31978 run_test 816 "do not reset lru_resize on idle reconnect"
31979
31980 cleanup_817() {
31981         umount $tmpdir
31982         exportfs -u localhost:$DIR/nfsexp
31983         rm -rf $DIR/nfsexp
31984 }
31985
31986 test_817() {
31987         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31988
31989         mkdir -p $DIR/nfsexp
31990         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31991                 error "failed to export nfs"
31992
31993         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31994         stack_trap cleanup_817 EXIT
31995
31996         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31997                 error "failed to mount nfs to $tmpdir"
31998
31999         cp /bin/true $tmpdir
32000         $DIR/nfsexp/true || error "failed to execute 'true' command"
32001 }
32002 run_test 817 "nfsd won't cache write lock for exec file"
32003
32004 test_818() {
32005         test_mkdir -i0 -c1 $DIR/$tdir
32006         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
32007         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
32008         stop $SINGLEMDS
32009
32010         # restore osp-syn threads
32011         stack_trap "fail $SINGLEMDS"
32012
32013         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
32014         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
32015         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
32016                 error "start $SINGLEMDS failed"
32017         rm -rf $DIR/$tdir
32018
32019         local testid=$(echo $TESTNAME | tr '_' ' ')
32020
32021         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
32022                 grep "run LFSCK" || error "run LFSCK is not suggested"
32023 }
32024 run_test 818 "unlink with failed llog"
32025
32026 test_819a() {
32027         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32028         cancel_lru_locks osc
32029         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
32030         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
32031         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
32032         rm -f $TDIR/$tfile
32033 }
32034 run_test 819a "too big niobuf in read"
32035
32036 test_819b() {
32037         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
32038         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
32039         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32040         cancel_lru_locks osc
32041         sleep 1
32042         rm -f $TDIR/$tfile
32043 }
32044 run_test 819b "too big niobuf in write"
32045
32046
32047 function test_820_start_ost() {
32048         sleep 5
32049
32050         for num in $(seq $OSTCOUNT); do
32051                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
32052         done
32053 }
32054
32055 test_820() {
32056         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
32057
32058         mkdir $DIR/$tdir
32059         umount_client $MOUNT || error "umount failed"
32060         for num in $(seq $OSTCOUNT); do
32061                 stop ost$num
32062         done
32063
32064         # mount client with no active OSTs
32065         # so that the client can't initialize max LOV EA size
32066         # from OSC notifications
32067         mount_client $MOUNT || error "mount failed"
32068         # delay OST starting to keep this 0 max EA size for a while
32069         test_820_start_ost &
32070
32071         # create a directory on MDS2
32072         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
32073                 error "Failed to create directory"
32074         # open intent should update default EA size
32075         # see mdc_update_max_ea_from_body()
32076         # notice this is the very first RPC to MDS2
32077         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
32078         ret=$?
32079         echo $out
32080         # With SSK, this situation can lead to -EPERM being returned.
32081         # In that case, simply retry.
32082         if [ $ret -ne 0 ] && $SHARED_KEY; then
32083                 if echo "$out" | grep -q "not permitted"; then
32084                         cp /etc/services $DIR/$tdir/mds2
32085                         ret=$?
32086                 fi
32087         fi
32088         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
32089 }
32090 run_test 820 "update max EA from open intent"
32091
32092 test_823() {
32093         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
32094         local OST_MAX_PRECREATE=20000
32095
32096         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
32097                 skip "Need MDS version at least 2.14.56"
32098
32099         save_lustre_params mds1 \
32100                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
32101         do_facet $SINGLEMDS "$LCTL set_param -n \
32102                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
32103         do_facet $SINGLEMDS "$LCTL set_param -n \
32104                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
32105
32106         stack_trap "restore_lustre_params < $p; rm $p"
32107
32108         do_facet $SINGLEMDS "$LCTL set_param -n \
32109                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
32110
32111         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
32112                       osp.$FSNAME-OST0000*MDT0000.create_count")
32113         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
32114                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
32115         local expect_count=$(((($max/2)/256) * 256))
32116
32117         log "setting create_count to 100200:"
32118         log " -result- count: $count with max: $max, expecting: $expect_count"
32119
32120         [[ $count -eq expect_count ]] ||
32121                 error "Create count not set to max precreate."
32122 }
32123 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
32124
32125 test_831() {
32126         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
32127                 skip "Need MDS version 2.14.56"
32128
32129         local sync_changes=$(do_facet $SINGLEMDS \
32130                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32131
32132         [ "$sync_changes" -gt 100 ] &&
32133                 skip "Sync changes $sync_changes > 100 already"
32134
32135         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
32136
32137         $LFS mkdir -i 0 $DIR/$tdir
32138         $LFS setstripe -c 1 -i 0 $DIR/$tdir
32139
32140         save_lustre_params mds1 \
32141                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
32142         save_lustre_params mds1 \
32143                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
32144
32145         do_facet mds1 "$LCTL set_param -n \
32146                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
32147                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
32148         stack_trap "restore_lustre_params < $p" EXIT
32149
32150         createmany -o $DIR/$tdir/f- 1000
32151         unlinkmany $DIR/$tdir/f- 1000 &
32152         local UNLINK_PID=$!
32153
32154         while sleep 1; do
32155                 sync_changes=$(do_facet mds1 \
32156                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
32157                 # the check in the code is racy, fail the test
32158                 # if the value above the limit by 10.
32159                 [ $sync_changes -gt 110 ] && {
32160                         kill -2 $UNLINK_PID
32161                         wait
32162                         error "osp changes throttling failed, $sync_changes>110"
32163                 }
32164                 kill -0 $UNLINK_PID 2> /dev/null || break
32165         done
32166         wait
32167 }
32168 run_test 831 "throttling unlink/setattr queuing on OSP"
32169
32170 test_832() {
32171         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32172         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
32173                 skip "Need MDS version 2.15.52+"
32174         is_rmentry_supported || skip "rm_entry not supported"
32175
32176         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
32177         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
32178         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
32179                 error "mkdir remote_dir failed"
32180         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
32181                 error "mkdir striped_dir failed"
32182         touch $DIR/$tdir/file || error "touch file failed"
32183         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
32184         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
32185 }
32186 run_test 832 "lfs rm_entry"
32187
32188 test_833() {
32189         local file=$DIR/$tfile
32190
32191         stack_trap "rm -f $file" EXIT
32192         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
32193
32194         local wpid
32195         local rpid
32196         local rpid2
32197
32198         # Buffered I/O write
32199         (
32200                 while [ ! -e $DIR/sanity.833.lck ]; do
32201                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
32202                                 error "failed to write $file"
32203                         sleep 0.$((RANDOM % 4 + 1))
32204                 done
32205         )&
32206         wpid=$!
32207
32208         # Buffered I/O read
32209         (
32210                 while [ ! -e $DIR/sanity.833.lck ]; do
32211                         dd if=$file of=/dev/null bs=1M count=50 ||
32212                                 error "failed to read $file"
32213                         sleep 0.$((RANDOM % 4 + 1))
32214                 done
32215         )&
32216         rpid=$!
32217
32218         # Direct I/O read
32219         (
32220                 while [ ! -e $DIR/sanity.833.lck ]; do
32221                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32222                                 error "failed to read $file in direct I/O mode"
32223                         sleep 0.$((RANDOM % 4 + 1))
32224                 done
32225         )&
32226         rpid2=$!
32227
32228         sleep 30
32229         touch $DIR/sanity.833.lck
32230         wait $wpid || error "$?: buffered write failed"
32231         wait $rpid || error "$?: buffered read failed"
32232         wait $rpid2 || error "$?: direct read failed"
32233 }
32234 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32235
32236 test_842() {
32237         local oss1=$(facet_host ost1)
32238
32239         # Try to insert the module.  This will leave results in dmesg
32240         now=$(date +%s)
32241         log "STAMP $now" > /dev/kmsg
32242         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32243                 error "$oss1 load_module ldlm_extent failed"
32244
32245         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32246         do_node $oss1 rmmod -v ldlm_extent ||
32247                 error "rmmod failed (may trigger a failure in a later test)"
32248 }
32249 run_test 842 "Measure ldlm_extent performance"
32250
32251 test_850() {
32252         local dir=$DIR/$tdir
32253         local file=$dir/$tfile
32254         local statsfile=$dir/all_job_stats.txt
32255
32256         test_mkdir -p $dir || error "failed to create dir $dir"
32257         echo "abcdefg" > $file || error "failed to create file $file"
32258
32259         # read job_stats in the living system
32260         lljobstat -n 1 ||
32261                 error "failed to run lljobstat on living system"
32262
32263         $LCTL get_param *.*.job_stats > $statsfile
32264         lljobstat --statsfile=$statsfile ||
32265                 error "failed to run lljobstat on file $statsfile"
32266 }
32267 run_test 850 "lljobstat can parse living and aggregated job_stats"
32268
32269 test_851() {
32270         local dir=$DIR/$tdir
32271         local file=$dir/f_test_851_$$
32272         local report=/tmp/report_test_851_$$
32273         local fanotify_prog=monitor_lustrefs
32274         local pid
32275
32276         test_mkdir $dir || error "failed to create dir $dir"
32277
32278         $fanotify_prog $DIR > $report &
32279         pid=$!
32280
32281         sleep 1
32282         if ! kill -0 $pid; then
32283                 error "failed to start $fanoify_prog"
32284         fi
32285
32286         stack_trap "kill $pid"
32287         stack_trap "rm -f $report"
32288
32289         echo "1234567890" > $file
32290         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32291                 error "fanotify did not report anything after 30 seconds"
32292         grep -a -E "open.*:$file:" $report ||
32293                 error "no open event for writing $file"
32294         grep -a -E "write.*:$file:" $report ||
32295                 error "no write event for writing $file"
32296         grep -a -E "close.*:$file:" $report ||
32297                 error "no close event for writing $file"
32298
32299         > $report
32300         cat $file
32301         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32302                 error "fanotify did not report anything after 30 seconds"
32303         grep -a -E "open.*:$file:" $report ||
32304                 error "no open event for reading $file"
32305         grep -a -E "read.*:$file:" $report ||
32306                 error "no write event for reading $file"
32307         grep -a -E "close.*:$file:" $report ||
32308                 error "no close event for reading $file"
32309 }
32310 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32311
32312 test_852() {
32313         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32314         (( $MDS1_VERSION >= $(version_code 2.15.61) )) ||
32315                 skip "Need MDS version at least 2.15.61 for intent mkdir"
32316
32317         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
32318
32319         save_lustre_params client "llite.*.intent_mkdir" > $save
32320         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
32321         $LCTL set_param llite.*.intent_mkdir=1
32322
32323         test_mkdir -p -c$MDSCOUNT $DIR/$tdir
32324         if [ $MDSCOUNT -ge 2 ]; then
32325                 $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir ||
32326                         error "set default dirstripe failed"
32327         fi
32328
32329         mkdir $DIR/$tdir/tdir || error "mkdir tdir failed"
32330         mkdir $DIR/$tdir/tdir/tfile || error "mkdir tdir/tfile failed"
32331         touch -d "2020-08-25 15:08" $DIR/$tdir/tdir/tfile ||
32332                 error "touch time failed"
32333         chown 0:0 $DIR/$tdir/tdir/tfile || error "chown 0:0 tdir/tfile failed"
32334         chmod 755 $DIR/$tdir/tdir/tfile || error "chmod 755 tdir/tfile failed"
32335 }
32336 run_test 852 "mkdir using intent lock for striped directory"
32337
32338 #
32339 # tests that do cleanup/setup should be run at the end
32340 #
32341
32342 test_900() {
32343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32344         local ls
32345
32346         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32347         $LCTL set_param fail_loc=0x903
32348
32349         cancel_lru_locks MGC
32350
32351         FAIL_ON_ERROR=true cleanup
32352         FAIL_ON_ERROR=true setup
32353 }
32354 run_test 900 "umount should not race with any mgc requeue thread"
32355
32356 # LUS-6253/LU-11185
32357 test_901() {
32358         local old
32359         local count
32360         local oldc
32361         local newc
32362         local olds
32363         local news
32364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32365
32366         # some get_param have a bug to handle dot in param name
32367         cancel_lru_locks MGC
32368         old=$(mount -t lustre | wc -l)
32369         # 1 config+sptlrpc
32370         # 2 params
32371         # 3 nodemap
32372         # 4 IR
32373         old=$((old * 4))
32374         oldc=0
32375         count=0
32376         while [ $old -ne $oldc ]; do
32377                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32378                 sleep 1
32379                 ((count++))
32380                 if [ $count -ge $TIMEOUT ]; then
32381                         error "too large timeout"
32382                 fi
32383         done
32384         umount_client $MOUNT || error "umount failed"
32385         mount_client $MOUNT || error "mount failed"
32386         cancel_lru_locks MGC
32387         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32388
32389         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32390
32391         return 0
32392 }
32393 run_test 901 "don't leak a mgc lock on client umount"
32394
32395 # LU-13377
32396 test_902() {
32397         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32398                 skip "client does not have LU-13377 fix"
32399         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32400         $LCTL set_param fail_loc=0x1415
32401         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32402         cancel_lru_locks osc
32403         rm -f $DIR/$tfile
32404 }
32405 run_test 902 "test short write doesn't hang lustre"
32406
32407 # LU-14711
32408 test_903() {
32409         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32410         echo "blah" > $DIR/${tfile}-2
32411         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32412         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32413         $LCTL set_param fail_loc=0x417 fail_val=20
32414
32415         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32416         sleep 1 # To start the destroy
32417         wait_destroy_complete 150 || error "Destroy taking too long"
32418         cat $DIR/$tfile > /dev/null || error "Evicted"
32419 }
32420 run_test 903 "Test long page discard does not cause evictions"
32421
32422 test_904() {
32423         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32424         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32425                 grep -q project || skip "skip project quota not supported"
32426
32427         local testfile="$DIR/$tdir/$tfile"
32428         local xattr="trusted.projid"
32429         local projid
32430         local mdts=$(comma_list $(mdts_nodes))
32431         local saved=$(do_facet mds1 $LCTL get_param -n \
32432                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32433
32434         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32435         stack_trap "do_nodes $mdts $LCTL set_param \
32436                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32437
32438         mkdir -p $DIR/$tdir
32439         touch $testfile
32440         #hide projid xattr on server
32441         $LFS project -p 1 $testfile ||
32442                 error "set $testfile project id failed"
32443         getfattr -m - $testfile | grep $xattr &&
32444                 error "do not show trusted.projid when disabled on server"
32445         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32446         #should be hidden when projid is 0
32447         $LFS project -p 0 $testfile ||
32448                 error "set $testfile project id failed"
32449         getfattr -m - $testfile | grep $xattr &&
32450                 error "do not show trusted.projid with project ID 0"
32451
32452         #still can getxattr explicitly
32453         projid=$(getfattr -n $xattr $testfile |
32454                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32455         [ $projid == "0" ] ||
32456                 error "projid expected 0 not $projid"
32457
32458         #set the projid via setxattr
32459         setfattr -n $xattr -v "1000" $testfile ||
32460                 error "setattr failed with $?"
32461         projid=($($LFS project $testfile))
32462         [ ${projid[0]} == "1000" ] ||
32463                 error "projid expected 1000 not $projid"
32464
32465         #check the new projid via getxattr
32466         $LFS project -p 1001 $testfile ||
32467                 error "set $testfile project id failed"
32468         getfattr -m - $testfile | grep $xattr ||
32469                 error "should show trusted.projid when project ID != 0"
32470         projid=$(getfattr -n $xattr $testfile |
32471                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32472         [ $projid == "1001" ] ||
32473                 error "projid expected 1001 not $projid"
32474
32475         #try to set invalid projid
32476         setfattr -n $xattr -v "4294967295" $testfile &&
32477                 error "set invalid projid should fail"
32478
32479         #remove the xattr means setting projid to 0
32480         setfattr -x $xattr $testfile ||
32481                 error "setfattr failed with $?"
32482         projid=($($LFS project $testfile))
32483         [ ${projid[0]} == "0" ] ||
32484                 error "projid expected 0 not $projid"
32485
32486         #should be hidden when parent has inherit flag and same projid
32487         $LFS project -srp 1002 $DIR/$tdir ||
32488                 error "set $tdir project id failed"
32489         getfattr -m - $testfile | grep $xattr &&
32490                 error "do not show trusted.projid with inherit flag"
32491
32492         #still can getxattr explicitly
32493         projid=$(getfattr -n $xattr $testfile |
32494                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32495         [ $projid == "1002" ] ||
32496                 error "projid expected 1002 not $projid"
32497 }
32498 run_test 904 "virtual project ID xattr"
32499
32500 # LU-8582
32501 test_905() {
32502         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32503                 skip "need OST version >= 2.15.50.220 for fail_loc"
32504
32505         remote_ost_nodsh && skip "remote OST with nodsh"
32506         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32507
32508         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32509
32510         #define OBD_FAIL_OST_OPCODE 0x253
32511         # OST_LADVISE = 21
32512         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32513         $LFS ladvise -a willread $DIR/$tfile &&
32514                 error "unexpected success of ladvise with fault injection"
32515         $LFS ladvise -a willread $DIR/$tfile |&
32516                 grep -q "Operation not supported"
32517         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32518 }
32519 run_test 905 "bad or new opcode should not stuck client"
32520
32521 test_906() {
32522         grep -q io_uring_setup /proc/kallsyms ||
32523                 skip "Client OS does not support io_uring I/O engine"
32524         io_uring_probe || skip "kernel does not support io_uring fully"
32525         which fio || skip_env "no fio installed"
32526         fio --enghelp | grep -q io_uring ||
32527                 skip_env "fio does not support io_uring I/O engine"
32528
32529         local file=$DIR/$tfile
32530         local ioengine="io_uring"
32531         local numjobs=2
32532         local size=50M
32533
32534         fio --name=seqwrite --ioengine=$ioengine        \
32535                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32536                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32537                 error "fio seqwrite $file failed"
32538
32539         fio --name=seqread --ioengine=$ioengine \
32540                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32541                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32542                 error "fio seqread $file failed"
32543
32544         rm -f $file || error "rm -f $file failed"
32545 }
32546 run_test 906 "Simple test for io_uring I/O engine via fio"
32547
32548 test_907() {
32549         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32550
32551         # set stripe size to max rpc size
32552         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32553         $LFS getstripe $DIR/$tfile
32554 #define OBD_FAIL_OST_EROFS               0x216
32555         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32556
32557         local bs=$((max_pages * PAGE_SIZE / 16))
32558
32559         # write full one stripe and one block
32560         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32561
32562         rm $DIR/$tfile || error "rm failed"
32563 }
32564 run_test 907 "write rpc error during unlink"
32565
32566 complete_test $SECONDS
32567 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32568 check_and_cleanup_lustre
32569 if [ "$I_MOUNTED" != "yes" ]; then
32570         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32571 fi
32572 exit_status