Whamcloud - gitweb
LU-4341 tests: re-enable SLES sanity test_170 test_243
[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 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 if [ -r /etc/redhat-release ]; then
86         rhel_version=$(cat /etc/redhat-release |
87                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
88         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
89                 # disable test_906 temporarily until rhel9.3 solves the
90                 # failure on fio io_uring I/O engine.
91                 always_except LU-17289 906
92         fi
93 fi
94
95 build_test_filter
96 FAIL_ON_ERROR=false
97
98 cleanup() {
99         echo -n "cln.."
100         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
101         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
102 }
103 setup() {
104         echo -n "mnt.."
105         load_modules
106         setupall || exit 10
107         echo "done"
108 }
109
110 check_swap_layouts_support()
111 {
112         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
113                 skip "Does not support layout lock."
114 }
115
116 check_swap_layout_no_dom()
117 {
118         local FOLDER=$1
119         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
120         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
121 }
122
123 check_and_setup_lustre
124 DIR=${DIR:-$MOUNT}
125 assert_DIR
126
127 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
128
129 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
130 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
131 rm -rf $DIR/[Rdfs][0-9]*
132
133 # $RUNAS_ID may get set incorrectly somewhere else
134 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
135         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
136
137 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
138
139 if [ "${ONLY}" = "MOUNT" ] ; then
140         echo "Lustre is up, please go on"
141         exit
142 fi
143
144 echo "preparing for tests involving mounts"
145 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
146 touch $EXT2_DEV
147 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
148 echo # add a newline after mke2fs.
149
150 umask 077
151
152 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
153
154 # ensure all internal functions know we want full debug
155 export PTLDEBUG=all
156 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
157
158 test_0a() {
159         touch $DIR/$tfile
160         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
161         rm $DIR/$tfile
162         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
163 }
164 run_test 0a "touch; rm ====================="
165
166 test_0b() {
167         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
168         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
169 }
170 run_test 0b "chmod 0755 $DIR ============================="
171
172 test_0c() {
173         $LCTL get_param mdc.*.import | grep "state: FULL" ||
174                 error "import not FULL"
175         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
176                 error "bad target"
177 }
178 run_test 0c "check import proc"
179
180 test_0d() { # LU-3397
181         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
182                 skip "proc exports not supported before 2.10.57"
183
184         local mgs_exp="mgs.MGS.exports"
185         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
186         local exp_client_nid
187         local exp_client_version
188         local exp_val
189         local imp_val
190         local temp_imp=$DIR/$tfile.import
191         local temp_exp=$DIR/$tfile.export
192
193         # save mgc import file to $temp_imp
194         $LCTL get_param mgc.*.import | tee $temp_imp
195         # Check if client uuid is found in MGS export
196         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
197                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
198                         $client_uuid ] &&
199                         break;
200         done
201         # save mgs export file to $temp_exp
202         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
203
204         # Compare the value of field "connect_flags"
205         imp_val=$(grep "connect_flags" $temp_imp)
206         exp_val=$(grep "connect_flags" $temp_exp)
207         [ "$exp_val" == "$imp_val" ] ||
208                 error "export flags '$exp_val' != import flags '$imp_val'"
209
210         # Compare client versions.  Only compare top-3 fields for compatibility
211         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
212         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
213         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
214         [ "$exp_val" == "$imp_val" ] ||
215                 error "exp version '$exp_client_version'($exp_val) != " \
216                         "'$(lustre_build_version client)'($imp_val)"
217 }
218 run_test 0d "check export proc ============================="
219
220 test_0e() { # LU-13417
221         (( $MDSCOUNT > 1 )) ||
222                 skip "We need at least 2 MDTs for this test"
223
224         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
225                 skip "Need server version at least 2.14.51"
226
227         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
228         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
229
230         [ $default_lmv_count -eq 1 ] ||
231                 error "$MOUNT default stripe count $default_lmv_count"
232
233         [ $default_lmv_index -eq -1 ] ||
234                 error "$MOUNT default stripe index $default_lmv_index"
235
236         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
237         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
238
239         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
240         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
241
242         [ $mdt_index1 -eq $mdt_index2 ] &&
243                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
244
245         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
246 }
247 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
248
249 test_0f() { # LU-17471
250         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
251                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
252         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
253            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
254                 skip "MDS was missing /proc/.../brw_stats value"
255
256         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
257         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
258
259         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
260 }
261 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
262
263 test_1() {
264         test_mkdir $DIR/$tdir
265         test_mkdir $DIR/$tdir/d2
266         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
267         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
268         rmdir $DIR/$tdir/d2
269         rmdir $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
271 }
272 run_test 1 "mkdir; remkdir; rmdir"
273
274 test_2() {
275         test_mkdir $DIR/$tdir
276         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
277         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
278         rm -r $DIR/$tdir
279         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
280 }
281 run_test 2 "mkdir; touch; rmdir; check file"
282
283 test_3() {
284         test_mkdir $DIR/$tdir
285         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
286         touch $DIR/$tdir/$tfile
287         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
288         rm -r $DIR/$tdir
289         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
290 }
291 run_test 3 "mkdir; touch; rmdir; check dir"
292
293 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
294 test_4() {
295         test_mkdir -i 1 $DIR/$tdir
296
297         touch $DIR/$tdir/$tfile ||
298                 error "Create file under remote directory failed"
299
300         rmdir $DIR/$tdir &&
301                 error "Expect error removing in-use dir $DIR/$tdir"
302
303         test -d $DIR/$tdir || error "Remote directory disappeared"
304
305         rm -rf $DIR/$tdir || error "remove remote dir error"
306 }
307 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
308
309 test_5() {
310         test_mkdir $DIR/$tdir
311         test_mkdir $DIR/$tdir/d2
312         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
313         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
314         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
315 }
316 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
317
318 test_6a() {
319         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
320         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
321         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
322                 error "$tfile does not have perm 0666 or UID $UID"
323         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
324         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
325                 error "$tfile should be 0666 and owned by UID $UID"
326 }
327 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
328
329 test_6c() {
330         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
331
332         touch $DIR/$tfile
333         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
334         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
335                 error "$tfile should be owned by UID $RUNAS_ID"
336         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
337         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
338                 error "$tfile should be owned by UID $RUNAS_ID"
339 }
340 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
341
342 test_6e() {
343         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
344
345         touch $DIR/$tfile
346         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
347         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
348                 error "$tfile should be owned by GID $UID"
349         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
350         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
351                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
352 }
353 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
354
355 test_6g() {
356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
357
358         test_mkdir $DIR/$tdir
359         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
360         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
361         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
362         test_mkdir $DIR/$tdir/d/subdir
363         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
364                 error "$tdir/d/subdir should be GID $RUNAS_GID"
365         if [[ $MDSCOUNT -gt 1 ]]; then
366                 # check remote dir sgid inherite
367                 $LFS mkdir -i 0 $DIR/$tdir.local ||
368                         error "mkdir $tdir.local failed"
369                 chmod g+s $DIR/$tdir.local ||
370                         error "chmod $tdir.local failed"
371                 chgrp $RUNAS_GID $DIR/$tdir.local ||
372                         error "chgrp $tdir.local failed"
373                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
374                         error "mkdir $tdir.remote failed"
375                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
376                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
377                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
378                         error "$tdir.remote should be mode 02755"
379         fi
380 }
381 run_test 6g "verify new dir in sgid dir inherits group"
382
383 test_6h() { # bug 7331
384         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
385
386         touch $DIR/$tfile || error "touch failed"
387         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
388         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
389                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
390         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
391                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
392 }
393 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
394
395 test_7a() {
396         test_mkdir $DIR/$tdir
397         $MCREATE $DIR/$tdir/$tfile
398         chmod 0666 $DIR/$tdir/$tfile
399         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
400                 error "$tdir/$tfile should be mode 0666"
401 }
402 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
403
404 test_7b() {
405         if [ ! -d $DIR/$tdir ]; then
406                 test_mkdir $DIR/$tdir
407         fi
408         $MCREATE $DIR/$tdir/$tfile
409         echo -n foo > $DIR/$tdir/$tfile
410         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
411         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
412 }
413 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
414
415 test_8() {
416         test_mkdir $DIR/$tdir
417         touch $DIR/$tdir/$tfile
418         chmod 0666 $DIR/$tdir/$tfile
419         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
420                 error "$tfile mode not 0666"
421 }
422 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
423
424 test_9() {
425         test_mkdir $DIR/$tdir
426         test_mkdir $DIR/$tdir/d2
427         test_mkdir $DIR/$tdir/d2/d3
428         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
429 }
430 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
431
432 test_10() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         touch $DIR/$tdir/d2/$tfile
436         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
437                 error "$tdir/d2/$tfile not a file"
438 }
439 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
440
441 test_11() {
442         test_mkdir $DIR/$tdir
443         test_mkdir $DIR/$tdir/d2
444         chmod 0666 $DIR/$tdir/d2
445         chmod 0705 $DIR/$tdir/d2
446         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
447                 error "$tdir/d2 mode not 0705"
448 }
449 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
450
451 test_12() {
452         test_mkdir $DIR/$tdir
453         touch $DIR/$tdir/$tfile
454         chmod 0666 $DIR/$tdir/$tfile
455         chmod 0654 $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
457                 error "$tdir/d2 mode not 0654"
458 }
459 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
460
461 test_13() {
462         test_mkdir $DIR/$tdir
463         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
464         >  $DIR/$tdir/$tfile
465         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
466                 error "$tdir/$tfile size not 0 after truncate"
467 }
468 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
469
470 test_14() {
471         test_mkdir $DIR/$tdir
472         touch $DIR/$tdir/$tfile
473         rm $DIR/$tdir/$tfile
474         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
475 }
476 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
477
478 test_15() {
479         test_mkdir $DIR/$tdir
480         touch $DIR/$tdir/$tfile
481         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
482         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
483                 error "$tdir/${tfile_2} not a file after rename"
484         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
485 }
486 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
487
488 test_16() {
489         test_mkdir $DIR/$tdir
490         touch $DIR/$tdir/$tfile
491         rm -rf $DIR/$tdir/$tfile
492         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
493 }
494 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
495
496 test_17a() {
497         test_mkdir $DIR/$tdir
498         touch $DIR/$tdir/$tfile
499         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
500         ls -l $DIR/$tdir
501         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
502                 error "$tdir/l-exist not a symlink"
503         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
504                 error "$tdir/l-exist not referencing a file"
505         rm -f $DIR/$tdir/l-exist
506         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
507 }
508 run_test 17a "symlinks: create, remove (real)"
509
510 test_17b() {
511         test_mkdir $DIR/$tdir
512         ln -s no-such-file $DIR/$tdir/l-dangle
513         ls -l $DIR/$tdir
514         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
515                 error "$tdir/l-dangle not referencing no-such-file"
516         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
517                 error "$tdir/l-dangle not referencing non-existent file"
518         rm -f $DIR/$tdir/l-dangle
519         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
520 }
521 run_test 17b "symlinks: create, remove (dangling)"
522
523 test_17c() { # bug 3440 - don't save failed open RPC for replay
524         test_mkdir $DIR/$tdir
525         ln -s foo $DIR/$tdir/$tfile
526         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
527 }
528 run_test 17c "symlinks: open dangling (should return error)"
529
530 test_17d() {
531         test_mkdir $DIR/$tdir
532         ln -s foo $DIR/$tdir/$tfile
533         touch $DIR/$tdir/$tfile || error "creating to new symlink"
534 }
535 run_test 17d "symlinks: create dangling"
536
537 test_17e() {
538         test_mkdir $DIR/$tdir
539         local foo=$DIR/$tdir/$tfile
540         ln -s $foo $foo || error "create symlink failed"
541         ls -l $foo || error "ls -l failed"
542         ls $foo && error "ls not failed" || true
543 }
544 run_test 17e "symlinks: create recursive symlink (should return error)"
545
546 test_17f() {
547         test_mkdir $DIR/$tdir
548         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
549         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
550         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
551         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
552         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
553         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
554         ls -l  $DIR/$tdir
555 }
556 run_test 17f "symlinks: long and very long symlink name"
557
558 # str_repeat(S, N) generate a string that is string S repeated N times
559 str_repeat() {
560         local s=$1
561         local n=$2
562         local ret=''
563         while [ $((n -= 1)) -ge 0 ]; do
564                 ret=$ret$s
565         done
566         echo $ret
567 }
568
569 # Long symlinks and LU-2241
570 test_17g() {
571         test_mkdir $DIR/$tdir
572         local TESTS="59 60 61 4094 4095"
573
574         # Fix for inode size boundary in 2.1.4
575         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
576                 TESTS="4094 4095"
577
578         # Patch not applied to 2.2 or 2.3 branches
579         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
580         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
581                 TESTS="4094 4095"
582
583         for i in $TESTS; do
584                 local SYMNAME=$(str_repeat 'x' $i)
585                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
586                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
587         done
588 }
589 run_test 17g "symlinks: really long symlink name and inode boundaries"
590
591 test_17h() { #bug 17378
592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
593         remote_mds_nodsh && skip "remote MDS with nodsh"
594
595         local mdt_idx
596
597         test_mkdir $DIR/$tdir
598         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
599         $LFS setstripe -c -1 $DIR/$tdir
600         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
601         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
602         touch $DIR/$tdir/$tfile || true
603 }
604 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
605
606 test_17i() { #bug 20018
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         remote_mds_nodsh && skip "remote MDS with nodsh"
609
610         local foo=$DIR/$tdir/$tfile
611         local mdt_idx
612
613         test_mkdir -c1 $DIR/$tdir
614         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
615         ln -s $foo $foo || error "create symlink failed"
616 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
617         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
618         ls -l $foo && error "error not detected"
619         return 0
620 }
621 run_test 17i "don't panic on short symlink (should return error)"
622
623 test_17k() { #bug 22301
624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
625         [[ -z "$(which rsync 2>/dev/null)" ]] &&
626                 skip "no rsync command"
627         rsync --help | grep -q xattr ||
628                 skip_env "$(rsync --version | head -n1) does not support xattrs"
629         test_mkdir $DIR/$tdir
630         test_mkdir $DIR/$tdir.new
631         touch $DIR/$tdir/$tfile
632         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
633         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
634                 error "rsync failed with xattrs enabled"
635 }
636 run_test 17k "symlinks: rsync with xattrs enabled"
637
638 test_17l() { # LU-279
639         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
640                 skip "no getfattr command"
641
642         test_mkdir $DIR/$tdir
643         touch $DIR/$tdir/$tfile
644         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
645         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
646                 # -h to not follow symlinks. -m '' to list all the xattrs.
647                 # grep to remove first line: '# file: $path'.
648                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
649                 do
650                         lgetxattr_size_check $path $xattr ||
651                                 error "lgetxattr_size_check $path $xattr failed"
652                 done
653         done
654 }
655 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
656
657 # LU-1540
658 test_17m() {
659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
660         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
661         remote_mds_nodsh && skip "remote MDS with nodsh"
662         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
663         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
664                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
665
666         local short_sym="0123456789"
667         local wdir=$DIR/$tdir
668         local i
669
670         test_mkdir $wdir
671         long_sym=$short_sym
672         # create a long symlink file
673         for ((i = 0; i < 4; ++i)); do
674                 long_sym=${long_sym}${long_sym}
675         done
676
677         echo "create 512 short and long symlink files under $wdir"
678         for ((i = 0; i < 256; ++i)); do
679                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
680                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
681         done
682
683         echo "erase them"
684         rm -f $wdir/*
685         sync
686         wait_delete_completed
687
688         echo "recreate the 512 symlink files with a shorter string"
689         for ((i = 0; i < 512; ++i)); do
690                 # rewrite the symlink file with a shorter string
691                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
692                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
693         done
694
695         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
696
697         echo "stop and checking mds${mds_index}:"
698         # e2fsck should not return error
699         stop mds${mds_index}
700         local devname=$(mdsdevname $mds_index)
701         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
702         rc=$?
703
704         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
705                 error "start mds${mds_index} failed"
706         df $MOUNT > /dev/null 2>&1
707         [ $rc -eq 0 ] ||
708                 error "e2fsck detected error for short/long symlink: rc=$rc"
709         rm -f $wdir/*
710 }
711 run_test 17m "run e2fsck against MDT which contains short/long symlink"
712
713 check_fs_consistency_17n() {
714         local mdt_index
715         local rc=0
716
717         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
718         # so it only check MDT1/MDT2 instead of all of MDTs.
719         for mdt_index in 1 2; do
720                 # e2fsck should not return error
721                 stop mds${mdt_index}
722                 local devname=$(mdsdevname $mdt_index)
723                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
724                         rc=$((rc + $?))
725
726                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
727                         error "mount mds$mdt_index failed"
728                 df $MOUNT > /dev/null 2>&1
729         done
730         return $rc
731 }
732
733 test_17n() {
734         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
736         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
737         remote_mds_nodsh && skip "remote MDS with nodsh"
738         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
739         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
740                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
741
742         local i
743
744         test_mkdir $DIR/$tdir
745         for ((i=0; i<10; i++)); do
746                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
747                         error "create remote dir error $i"
748                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
749                         error "create files under remote dir failed $i"
750         done
751
752         check_fs_consistency_17n ||
753                 error "e2fsck report error after create files under remote dir"
754
755         for ((i = 0; i < 10; i++)); do
756                 rm -rf $DIR/$tdir/remote_dir_${i} ||
757                         error "destroy remote dir error $i"
758         done
759
760         check_fs_consistency_17n ||
761                 error "e2fsck report error after unlink files under remote dir"
762
763         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
764                 skip "lustre < 2.4.50 does not support migrate mv"
765
766         for ((i = 0; i < 10; i++)); do
767                 mkdir -p $DIR/$tdir/remote_dir_${i}
768                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
769                         error "create files under remote dir failed $i"
770                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
771                         error "migrate remote dir error $i"
772         done
773         check_fs_consistency_17n || error "e2fsck report error after migration"
774
775         for ((i = 0; i < 10; i++)); do
776                 rm -rf $DIR/$tdir/remote_dir_${i} ||
777                         error "destroy remote dir error $i"
778         done
779
780         check_fs_consistency_17n || error "e2fsck report error after unlink"
781 }
782 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
783
784 test_17o() {
785         remote_mds_nodsh && skip "remote MDS with nodsh"
786         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
787                 skip "Need MDS version at least 2.3.64"
788
789         local wdir=$DIR/${tdir}o
790         local mdt_index
791         local rc=0
792
793         test_mkdir $wdir
794         touch $wdir/$tfile
795         mdt_index=$($LFS getstripe -m $wdir/$tfile)
796         mdt_index=$((mdt_index + 1))
797
798         cancel_lru_locks mdc
799         #fail mds will wait the failover finish then set
800         #following fail_loc to avoid interfer the recovery process.
801         fail mds${mdt_index}
802
803         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
804         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
805         ls -l $wdir/$tfile && rc=1
806         do_facet mds${mdt_index} lctl set_param fail_loc=0
807         [[ $rc -eq 0 ]] || error "stat file should fail"
808 }
809 run_test 17o "stat file with incompat LMA feature"
810
811 test_18() {
812         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
813         ls $DIR || error "Failed to ls $DIR: $?"
814 }
815 run_test 18 "touch .../f ; ls ... =============================="
816
817 test_19a() {
818         touch $DIR/$tfile
819         ls -l $DIR
820         rm $DIR/$tfile
821         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
822 }
823 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
824
825 test_19b() {
826         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
827 }
828 run_test 19b "ls -l .../f19 (should return error) =============="
829
830 test_19c() {
831         [ $RUNAS_ID -eq $UID ] &&
832                 skip_env "RUNAS_ID = UID = $UID -- skipping"
833
834         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
835 }
836 run_test 19c "$RUNAS touch .../f19 (should return error) =="
837
838 test_19d() {
839         cat $DIR/f19 && error || true
840 }
841 run_test 19d "cat .../f19 (should return error) =============="
842
843 test_20() {
844         touch $DIR/$tfile
845         rm $DIR/$tfile
846         touch $DIR/$tfile
847         rm $DIR/$tfile
848         touch $DIR/$tfile
849         rm $DIR/$tfile
850         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
851 }
852 run_test 20 "touch .../f ; ls -l ..."
853
854 test_21() {
855         test_mkdir $DIR/$tdir
856         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
857         ln -s dangle $DIR/$tdir/link
858         echo foo >> $DIR/$tdir/link
859         cat $DIR/$tdir/dangle
860         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
861         $CHECKSTAT -f -t file $DIR/$tdir/link ||
862                 error "$tdir/link not linked to a file"
863 }
864 run_test 21 "write to dangling link"
865
866 test_22() {
867         local wdir=$DIR/$tdir
868         test_mkdir $wdir
869         chown $RUNAS_ID:$RUNAS_GID $wdir
870         (cd $wdir || error "cd $wdir failed";
871                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
872                 $RUNAS tar xf -)
873         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
874         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
875         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
876                 error "checkstat -u failed"
877 }
878 run_test 22 "unpack tar archive as non-root user"
879
880 # was test_23
881 test_23a() {
882         test_mkdir $DIR/$tdir
883         local file=$DIR/$tdir/$tfile
884
885         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
886         openfile -f O_CREAT:O_EXCL $file &&
887                 error "$file recreate succeeded" || true
888 }
889 run_test 23a "O_CREAT|O_EXCL in subdir"
890
891 test_23b() { # bug 18988
892         test_mkdir $DIR/$tdir
893         local file=$DIR/$tdir/$tfile
894
895         rm -f $file
896         echo foo > $file || error "write filed"
897         echo bar >> $file || error "append filed"
898         $CHECKSTAT -s 8 $file || error "wrong size"
899         rm $file
900 }
901 run_test 23b "O_APPEND check"
902
903 # LU-9409, size with O_APPEND and tiny writes
904 test_23c() {
905         local file=$DIR/$tfile
906
907         # single dd
908         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
909         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
910         rm -f $file
911
912         # racing tiny writes
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
914         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
915         wait
916         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
917         rm -f $file
918
919         #racing tiny & normal writes
920         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
921         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
922         wait
923         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
924         rm -f $file
925
926         #racing tiny & normal writes 2, ugly numbers
927         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
928         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
929         wait
930         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
931         rm -f $file
932 }
933 run_test 23c "O_APPEND size checks for tiny writes"
934
935 # LU-11069 file offset is correct after appending writes
936 test_23d() {
937         local file=$DIR/$tfile
938         local offset
939
940         echo CentaurHauls > $file
941         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
942         if ((offset != 26)); then
943                 error "wrong offset, expected 26, got '$offset'"
944         fi
945 }
946 run_test 23d "file offset is correct after appending writes"
947
948 # rename sanity
949 test_24a() {
950         echo '-- same directory rename'
951         test_mkdir $DIR/$tdir
952         touch $DIR/$tdir/$tfile.1
953         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24a "rename file to non-existent target"
957
958 test_24b() {
959         test_mkdir $DIR/$tdir
960         touch $DIR/$tdir/$tfile.{1,2}
961         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
962         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
963         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
964 }
965 run_test 24b "rename file to existing target"
966
967 test_24c() {
968         test_mkdir $DIR/$tdir
969         test_mkdir $DIR/$tdir/d$testnum.1
970         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
971         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
972         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
973 }
974 run_test 24c "rename directory to non-existent target"
975
976 test_24d() {
977         test_mkdir -c1 $DIR/$tdir
978         test_mkdir -c1 $DIR/$tdir/d$testnum.1
979         test_mkdir -c1 $DIR/$tdir/d$testnum.2
980         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
981         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
982         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
983 }
984 run_test 24d "rename directory to existing target"
985
986 test_24e() {
987         echo '-- cross directory renames --'
988         test_mkdir $DIR/R5a
989         test_mkdir $DIR/R5b
990         touch $DIR/R5a/f
991         mv $DIR/R5a/f $DIR/R5b/g
992         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
993         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
994 }
995 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
996
997 test_24f() {
998         test_mkdir $DIR/R6a
999         test_mkdir $DIR/R6b
1000         touch $DIR/R6a/f $DIR/R6b/g
1001         mv $DIR/R6a/f $DIR/R6b/g
1002         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1003         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1004 }
1005 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1006
1007 test_24g() {
1008         test_mkdir $DIR/R7a
1009         test_mkdir $DIR/R7b
1010         test_mkdir $DIR/R7a/d
1011         mv $DIR/R7a/d $DIR/R7b/e
1012         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1013         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1014 }
1015 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1016
1017 test_24h() {
1018         test_mkdir -c1 $DIR/R8a
1019         test_mkdir -c1 $DIR/R8b
1020         test_mkdir -c1 $DIR/R8a/d
1021         test_mkdir -c1 $DIR/R8b/e
1022         mrename $DIR/R8a/d $DIR/R8b/e
1023         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1024         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1025 }
1026 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1027
1028 test_24i() {
1029         echo "-- rename error cases"
1030         test_mkdir $DIR/R9
1031         test_mkdir $DIR/R9/a
1032         touch $DIR/R9/f
1033         mrename $DIR/R9/f $DIR/R9/a
1034         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1035         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1036         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1037 }
1038 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1039
1040 test_24j() {
1041         test_mkdir $DIR/R10
1042         mrename $DIR/R10/f $DIR/R10/g
1043         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1044         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1045         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1046 }
1047 run_test 24j "source does not exist ============================"
1048
1049 test_24k() {
1050         test_mkdir $DIR/R11a
1051         test_mkdir $DIR/R11a/d
1052         touch $DIR/R11a/f
1053         mv $DIR/R11a/f $DIR/R11a/d
1054         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1055         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1056 }
1057 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1058
1059 # bug 2429 - rename foo foo foo creates invalid file
1060 test_24l() {
1061         f="$DIR/f24l"
1062         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1063 }
1064 run_test 24l "Renaming a file to itself ========================"
1065
1066 test_24m() {
1067         f="$DIR/f24m"
1068         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1069         # on ext3 this does not remove either the source or target files
1070         # though the "expected" operation would be to remove the source
1071         $CHECKSTAT -t file ${f} || error "${f} missing"
1072         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1073 }
1074 run_test 24m "Renaming a file to a hard link to itself ========="
1075
1076 test_24n() {
1077     f="$DIR/f24n"
1078     # this stats the old file after it was renamed, so it should fail
1079     touch ${f}
1080     $CHECKSTAT ${f} || error "${f} missing"
1081     mv ${f} ${f}.rename
1082     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1083     $CHECKSTAT -a ${f} || error "${f} exists"
1084 }
1085 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1086
1087 test_24o() {
1088         test_mkdir $DIR/$tdir
1089         rename_many -s random -v -n 10 $DIR/$tdir
1090 }
1091 run_test 24o "rename of files during htree split"
1092
1093 test_24p() {
1094         test_mkdir $DIR/R12a
1095         test_mkdir $DIR/R12b
1096         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1097         mrename $DIR/R12a $DIR/R12b
1098         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1099         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1100         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1101         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1102 }
1103 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1104
1105 cleanup_multiop_pause() {
1106         trap 0
1107         kill -USR1 $MULTIPID
1108 }
1109
1110 test_24q() {
1111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1112
1113         test_mkdir $DIR/R13a
1114         test_mkdir $DIR/R13b
1115         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1116         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1117         MULTIPID=$!
1118
1119         trap cleanup_multiop_pause EXIT
1120         mrename $DIR/R13a $DIR/R13b
1121         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1122         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1123         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1124         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1125         cleanup_multiop_pause
1126         wait $MULTIPID || error "multiop close failed"
1127 }
1128 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1129
1130 test_24r() { #bug 3789
1131         test_mkdir $DIR/R14a
1132         test_mkdir $DIR/R14a/b
1133         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1134         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1135         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1136 }
1137 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1138
1139 test_24s() {
1140         test_mkdir $DIR/R15a
1141         test_mkdir $DIR/R15a/b
1142         test_mkdir $DIR/R15a/b/c
1143         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1145         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1146 }
1147 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1148
1149 test_24t() {
1150         test_mkdir $DIR/R16a
1151         test_mkdir $DIR/R16a/b
1152         test_mkdir $DIR/R16a/b/c
1153         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1154         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1155         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1156 }
1157 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1158
1159 test_24u() { # bug12192
1160         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1161         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1162 }
1163 run_test 24u "create stripe file"
1164
1165 simple_cleanup_common() {
1166         local createmany=$1
1167         local rc=0
1168
1169         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1170
1171         local start=$SECONDS
1172
1173         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1174         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1175         rc=$?
1176         wait_delete_completed
1177         echo "cleanup time $((SECONDS - start))"
1178         return $rc
1179 }
1180
1181 max_pages_per_rpc() {
1182         local mdtname="$(printf "MDT%04x" ${1:-0})"
1183         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1184 }
1185
1186 test_24v() {
1187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1188
1189         local nrfiles=${COUNT:-100000}
1190         local fname="$DIR/$tdir/$tfile"
1191
1192         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1193         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1194
1195         test_mkdir "$(dirname $fname)"
1196         # assume MDT0000 has the fewest inodes
1197         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1198         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1199         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1200
1201         stack_trap "simple_cleanup_common $nrfiles"
1202
1203         createmany -m "$fname" $nrfiles
1204
1205         cancel_lru_locks mdc
1206         lctl set_param mdc.*.stats clear
1207
1208         # was previously test_24D: LU-6101
1209         # readdir() returns correct number of entries after cursor reload
1210         local num_ls=$(ls $DIR/$tdir | wc -l)
1211         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1212         local num_all=$(ls -a $DIR/$tdir | wc -l)
1213         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1214                 [ $num_all -ne $((nrfiles + 2)) ]; then
1215                         error "Expected $nrfiles files, got $num_ls " \
1216                                 "($num_uniq unique $num_all .&..)"
1217         fi
1218         # LU-5 large readdir
1219         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1220         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1221         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1222         # take into account of overhead in lu_dirpage header and end mark in
1223         # each page, plus one in rpc_num calculation.
1224         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1225         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1226         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1227         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1228         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1229         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1230         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1231         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1232                 error "large readdir doesn't take effect: " \
1233                       "$mds_readpage should be about $rpc_max"
1234 }
1235 run_test 24v "list large directory (test hash collision, b=17560)"
1236
1237 test_24w() { # bug21506
1238         SZ1=234852
1239         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1240         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1241         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1242         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1243         [[ "$SZ1" -eq "$SZ2" ]] ||
1244                 error "Error reading at the end of the file $tfile"
1245 }
1246 run_test 24w "Reading a file larger than 4Gb"
1247
1248 test_24x() {
1249         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1251         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1252                 skip "Need MDS version at least 2.7.56"
1253
1254         local MDTIDX=1
1255         local remote_dir=$DIR/$tdir/remote_dir
1256
1257         test_mkdir $DIR/$tdir
1258         $LFS mkdir -i $MDTIDX $remote_dir ||
1259                 error "create remote directory failed"
1260
1261         test_mkdir $DIR/$tdir/src_dir
1262         touch $DIR/$tdir/src_file
1263         test_mkdir $remote_dir/tgt_dir
1264         touch $remote_dir/tgt_file
1265
1266         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1267                 error "rename dir cross MDT failed!"
1268
1269         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1270                 error "rename file cross MDT failed!"
1271
1272         touch $DIR/$tdir/ln_file
1273         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1274                 error "ln file cross MDT failed"
1275
1276         rm -rf $DIR/$tdir || error "Can not delete directories"
1277 }
1278 run_test 24x "cross MDT rename/link"
1279
1280 test_24y() {
1281         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1283
1284         local remote_dir=$DIR/$tdir/remote_dir
1285         local mdtidx=1
1286
1287         test_mkdir $DIR/$tdir
1288         $LFS mkdir -i $mdtidx $remote_dir ||
1289                 error "create remote directory failed"
1290
1291         test_mkdir $remote_dir/src_dir
1292         touch $remote_dir/src_file
1293         test_mkdir $remote_dir/tgt_dir
1294         touch $remote_dir/tgt_file
1295
1296         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1297                 error "rename subdir in the same remote dir failed!"
1298
1299         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1300                 error "rename files in the same remote dir failed!"
1301
1302         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1303                 error "link files in the same remote dir failed!"
1304
1305         rm -rf $DIR/$tdir || error "Can not delete directories"
1306 }
1307 run_test 24y "rename/link on the same dir should succeed"
1308
1309 test_24z() {
1310         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1311         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1312                 skip "Need MDS version at least 2.12.51"
1313
1314         local index
1315
1316         for index in 0 1; do
1317                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1318                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1319         done
1320
1321         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1324         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1325
1326         local mdts=$(comma_list $(mdts_nodes))
1327
1328         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1329         stack_trap "do_nodes $mdts $LCTL \
1330                 set_param mdt.*.enable_remote_rename=1" EXIT
1331
1332         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1333
1334         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1335         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1336 }
1337 run_test 24z "cross-MDT rename is done as cp"
1338
1339 test_24A() { # LU-3182
1340         local NFILES=5000
1341
1342         test_mkdir $DIR/$tdir
1343         stack_trap "simple_cleanup_common $NFILES"
1344         createmany -m $DIR/$tdir/$tfile $NFILES
1345         local t=$(ls $DIR/$tdir | wc -l)
1346         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1347         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1348
1349         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1350                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1351 }
1352 run_test 24A "readdir() returns correct number of entries."
1353
1354 test_24B() { # LU-4805
1355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1356
1357         local count
1358
1359         test_mkdir $DIR/$tdir
1360         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1361                 error "create striped dir failed"
1362
1363         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1364         [ $count -eq 2 ] || error "Expected 2, got $count"
1365
1366         touch $DIR/$tdir/striped_dir/a
1367
1368         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1369         [ $count -eq 3 ] || error "Expected 3, got $count"
1370
1371         touch $DIR/$tdir/striped_dir/.f
1372
1373         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1374         [ $count -eq 4 ] || error "Expected 4, got $count"
1375
1376         rm -rf $DIR/$tdir || error "Can not delete directories"
1377 }
1378 run_test 24B "readdir for striped dir return correct number of entries"
1379
1380 test_24C() {
1381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1382
1383         mkdir $DIR/$tdir
1384         mkdir $DIR/$tdir/d0
1385         mkdir $DIR/$tdir/d1
1386
1387         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1388                 error "create striped dir failed"
1389
1390         cd $DIR/$tdir/d0/striped_dir
1391
1392         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1393         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1394         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1395
1396         [ "$d0_ino" = "$parent_ino" ] ||
1397                 error ".. wrong, expect $d0_ino, get $parent_ino"
1398
1399         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1400                 error "mv striped dir failed"
1401
1402         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1403
1404         [ "$d1_ino" = "$parent_ino" ] ||
1405                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1406 }
1407 run_test 24C "check .. in striped dir"
1408
1409 test_24E() {
1410         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1412
1413         mkdir -p $DIR/$tdir
1414         mkdir $DIR/$tdir/src_dir
1415         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1416                 error "create remote source failed"
1417
1418         touch $DIR/$tdir/src_dir/src_child/a
1419
1420         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1421                 error "create remote target dir failed"
1422
1423         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1424                 error "create remote target child failed"
1425
1426         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1427                 error "rename dir cross MDT failed!"
1428
1429         find $DIR/$tdir
1430
1431         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1432                 error "src_child still exists after rename"
1433
1434         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1435                 error "missing file(a) after rename"
1436
1437         rm -rf $DIR/$tdir || error "Can not delete directories"
1438 }
1439 run_test 24E "cross MDT rename/link"
1440
1441 test_24F () {
1442         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1443
1444         local repeats=1000
1445         [ "$SLOW" = "no" ] && repeats=100
1446
1447         mkdir -p $DIR/$tdir
1448
1449         echo "$repeats repeats"
1450         for ((i = 0; i < repeats; i++)); do
1451                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1452                 touch $DIR/$tdir/test/a || error "touch fails"
1453                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1454                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1455         done
1456
1457         true
1458 }
1459 run_test 24F "hash order vs readdir (LU-11330)"
1460
1461 test_24G () {
1462         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1463
1464         local ino1
1465         local ino2
1466
1467         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1468         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1469         touch $DIR/$tdir-0/f1 || error "touch f1"
1470         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1471         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1472         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1473         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1474         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1475 }
1476 run_test 24G "migrate symlink in rename"
1477
1478 test_24H() {
1479         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1480         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1481                 skip "MDT1 should be on another node"
1482
1483         test_mkdir -i 1 -c 1 $DIR/$tdir
1484 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1485         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1486         touch $DIR/$tdir/$tfile || error "touch failed"
1487 }
1488 run_test 24H "repeat FLD_QUERY rpc"
1489
1490 test_25a() {
1491         echo '== symlink sanity ============================================='
1492
1493         test_mkdir $DIR/d25
1494         ln -s d25 $DIR/s25
1495         touch $DIR/s25/foo ||
1496                 error "File creation in symlinked directory failed"
1497 }
1498 run_test 25a "create file in symlinked directory ==============="
1499
1500 test_25b() {
1501         [ ! -d $DIR/d25 ] && test_25a
1502         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1503 }
1504 run_test 25b "lookup file in symlinked directory ==============="
1505
1506 test_26a() {
1507         test_mkdir $DIR/d26
1508         test_mkdir $DIR/d26/d26-2
1509         ln -s d26/d26-2 $DIR/s26
1510         touch $DIR/s26/foo || error "File creation failed"
1511 }
1512 run_test 26a "multiple component symlink ======================="
1513
1514 test_26b() {
1515         test_mkdir -p $DIR/$tdir/d26-2
1516         ln -s $tdir/d26-2/foo $DIR/s26-2
1517         touch $DIR/s26-2 || error "File creation failed"
1518 }
1519 run_test 26b "multiple component symlink at end of lookup ======"
1520
1521 test_26c() {
1522         test_mkdir $DIR/d26.2
1523         touch $DIR/d26.2/foo
1524         ln -s d26.2 $DIR/s26.2-1
1525         ln -s s26.2-1 $DIR/s26.2-2
1526         ln -s s26.2-2 $DIR/s26.2-3
1527         chmod 0666 $DIR/s26.2-3/foo
1528 }
1529 run_test 26c "chain of symlinks"
1530
1531 # recursive symlinks (bug 439)
1532 test_26d() {
1533         ln -s d26-3/foo $DIR/d26-3
1534 }
1535 run_test 26d "create multiple component recursive symlink"
1536
1537 test_26e() {
1538         [ ! -h $DIR/d26-3 ] && test_26d
1539         rm $DIR/d26-3
1540 }
1541 run_test 26e "unlink multiple component recursive symlink"
1542
1543 # recursive symlinks (bug 7022)
1544 test_26f() {
1545         test_mkdir $DIR/$tdir
1546         test_mkdir $DIR/$tdir/$tfile
1547         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1548         test_mkdir -p lndir/bar1
1549         test_mkdir $DIR/$tdir/$tfile/$tfile
1550         cd $tfile                || error "cd $tfile failed"
1551         ln -s .. dotdot          || error "ln dotdot failed"
1552         ln -s dotdot/lndir lndir || error "ln lndir failed"
1553         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1554         output=`ls $tfile/$tfile/lndir/bar1`
1555         [ "$output" = bar1 ] && error "unexpected output"
1556         rm -r $tfile             || error "rm $tfile failed"
1557         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1558 }
1559 run_test 26f "rm -r of a directory which has recursive symlink"
1560
1561 test_27a() {
1562         test_mkdir $DIR/$tdir
1563         $LFS getstripe $DIR/$tdir
1564         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1565         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1566         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1567 }
1568 run_test 27a "one stripe file"
1569
1570 test_27b() {
1571         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1572
1573         test_mkdir $DIR/$tdir
1574         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1575         $LFS getstripe -c $DIR/$tdir/$tfile
1576         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1577                 error "two-stripe file doesn't have two stripes"
1578
1579         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1580 }
1581 run_test 27b "create and write to two stripe file"
1582
1583 # 27c family tests specific striping, setstripe -o
1584 test_27ca() {
1585         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1586         test_mkdir -p $DIR/$tdir
1587         local osts="1"
1588
1589         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1590         $LFS getstripe -i $DIR/$tdir/$tfile
1591         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1592                 error "stripe not on specified OST"
1593
1594         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1595 }
1596 run_test 27ca "one stripe on specified OST"
1597
1598 test_27cb() {
1599         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1600         test_mkdir -p $DIR/$tdir
1601         local osts="1,0"
1602         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1603         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1604         echo "$getstripe"
1605
1606         # Strip getstripe output to a space separated list of OSTs
1607         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1608                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1609         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1610                 error "stripes not on specified OSTs"
1611
1612         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1613 }
1614 run_test 27cb "two stripes on specified OSTs"
1615
1616 test_27cc() {
1617         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1618         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1619                 skip "server does not support overstriping"
1620
1621         test_mkdir -p $DIR/$tdir
1622         local osts="0,0"
1623         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1624         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1625         echo "$getstripe"
1626
1627         # Strip getstripe output to a space separated list of OSTs
1628         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1629                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1630         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1631                 error "stripes not on specified OSTs"
1632
1633         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1634 }
1635 run_test 27cc "two stripes on the same OST"
1636
1637 test_27cd() {
1638         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1639         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1640                 skip "server does not support overstriping"
1641         test_mkdir -p $DIR/$tdir
1642         local osts="0,1,1,0"
1643         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1644         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1645         echo "$getstripe"
1646
1647         # Strip getstripe output to a space separated list of OSTs
1648         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1649                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1650         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1651                 error "stripes not on specified OSTs"
1652
1653         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1654 }
1655 run_test 27cd "four stripes on two OSTs"
1656
1657 test_27ce() {
1658         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1659                 skip_env "too many osts, skipping"
1660         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1661                 skip "server does not support overstriping"
1662         # We do one more stripe than we have OSTs
1663         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1664                 skip_env "ea_inode feature disabled"
1665
1666         test_mkdir -p $DIR/$tdir
1667         local osts=""
1668         for i in $(seq 0 $OSTCOUNT);
1669         do
1670                 osts=$osts"0"
1671                 if [ $i -ne $OSTCOUNT ]; then
1672                         osts=$osts","
1673                 fi
1674         done
1675         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1676         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1677         echo "$getstripe"
1678
1679         # Strip getstripe output to a space separated list of OSTs
1680         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1681                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1682         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1683                 error "stripes not on specified OSTs"
1684
1685         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1686 }
1687 run_test 27ce "more stripes than OSTs with -o"
1688
1689 test_27cf() {
1690         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1691         local pid=0
1692
1693         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1694         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1695         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1696         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1697                 error "failed to set $osp_proc=0"
1698
1699         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1700         pid=$!
1701         sleep 1
1702         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1703         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1704                 error "failed to set $osp_proc=1"
1705         wait $pid
1706         [[ $pid -ne 0 ]] ||
1707                 error "should return error due to $osp_proc=0"
1708 }
1709 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1710
1711 test_27cg() {
1712         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1713                 skip "server does not support overstriping"
1714         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1715         large_xattr_enabled || skip_env "ea_inode feature disabled"
1716
1717         local osts="0"
1718
1719         for ((i=1;i<1000;i++)); do
1720                 osts+=",$((i % OSTCOUNT))"
1721         done
1722
1723         local mdts=$(comma_list $(mdts_nodes))
1724         local before=$(do_nodes $mdts \
1725                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1726                 awk '/many credits/{print $3}' |
1727                 calc_sum)
1728
1729         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1730         $LFS getstripe $DIR/$tfile | grep stripe
1731
1732         rm -f $DIR/$tfile || error "can't unlink"
1733
1734         after=$(do_nodes $mdts \
1735                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1736                 awk '/many credits/{print $3}' |
1737                 calc_sum)
1738
1739         (( before == after )) ||
1740                 error "too many credits happened: $after > $before"
1741 }
1742 run_test 27cg "1000 shouldn't cause too many credits"
1743
1744 test_27d() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1747                 error "setstripe failed"
1748         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1749         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1750 }
1751 run_test 27d "create file with default settings"
1752
1753 test_27e() {
1754         # LU-5839 adds check for existed layout before setting it
1755         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1756                 skip "Need MDS version at least 2.7.56"
1757
1758         test_mkdir $DIR/$tdir
1759         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1760         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1761         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1762 }
1763 run_test 27e "setstripe existing file (should return error)"
1764
1765 test_27f() {
1766         test_mkdir $DIR/$tdir
1767         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1768                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1769         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1770                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1772         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1773 }
1774 run_test 27f "setstripe with bad stripe size (should return error)"
1775
1776 test_27g() {
1777         test_mkdir $DIR/$tdir
1778         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1779         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1780                 error "$DIR/$tdir/$tfile has object"
1781 }
1782 run_test 27g "$LFS getstripe with no objects"
1783
1784 test_27ga() {
1785         test_mkdir $DIR/$tdir
1786         touch $DIR/$tdir/$tfile || error "touch failed"
1787         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1788         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1789         local rc=$?
1790         (( rc == 2 )) || error "getstripe did not return ENOENT"
1791
1792         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1793                         2>&1 > /dev/null)
1794         [[ $err_msg =~ "typo" ]] ||
1795                 error "expected message with correct filename, got '$err_msg'"
1796 }
1797 run_test 27ga "$LFS getstripe with missing file (should return error)"
1798
1799 test_27i() {
1800         test_mkdir $DIR/$tdir
1801         touch $DIR/$tdir/$tfile || error "touch failed"
1802         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1803                 error "missing objects"
1804 }
1805 run_test 27i "$LFS getstripe with some objects"
1806
1807 test_27j() {
1808         test_mkdir $DIR/$tdir
1809         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1810                 error "setstripe failed" || true
1811 }
1812 run_test 27j "setstripe with bad stripe offset (should return error)"
1813
1814 test_27k() { # bug 2844
1815         test_mkdir $DIR/$tdir
1816         local file=$DIR/$tdir/$tfile
1817         local ll_max_blksize=$((4 * 1024 * 1024))
1818         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1819         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1820         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1821         dd if=/dev/zero of=$file bs=4k count=1
1822         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1823         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1824 }
1825 run_test 27k "limit i_blksize for broken user apps"
1826
1827 test_27l() {
1828         mcreate $DIR/$tfile || error "creating file"
1829         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1830                 error "setstripe should have failed" || true
1831 }
1832 run_test 27l "check setstripe permissions (should return error)"
1833
1834 test_27m() {
1835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1836
1837         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1838                 skip_env "multiple clients -- skipping"
1839
1840         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1841                    head -n1)
1842         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1843                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1844         fi
1845         stack_trap simple_cleanup_common
1846         test_mkdir $DIR/$tdir
1847         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1848         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1849                 error "dd should fill OST0"
1850         i=2
1851         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1852                 i=$((i + 1))
1853                 [ $i -gt 256 ] && break
1854         done
1855         i=$((i + 1))
1856         touch $DIR/$tdir/$tfile.$i
1857         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1858             awk '{print $1}'| grep -w "0") ] &&
1859                 error "OST0 was full but new created file still use it"
1860         i=$((i + 1))
1861         touch $DIR/$tdir/$tfile.$i
1862         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1863             awk '{print $1}'| grep -w "0") ] &&
1864                 error "OST0 was full but new created file still use it" || true
1865 }
1866 run_test 27m "create file while OST0 was full"
1867
1868 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1869 # if the OST isn't full anymore.
1870 reset_enospc() {
1871         local ostidx=${1:-""}
1872         local delay
1873         local ready
1874         local get_prealloc
1875
1876         local list=$(comma_list $(osts_nodes))
1877         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1878
1879         do_nodes $list lctl set_param fail_loc=0
1880         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1881         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1882                 awk '{print $1 * 2;exit;}')
1883         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1884                         grep -v \"^0$\""
1885         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1886 }
1887
1888 test_27n() {
1889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1891         remote_mds_nodsh && skip "remote MDS with nodsh"
1892         remote_ost_nodsh && skip "remote OST with nodsh"
1893
1894         reset_enospc
1895         rm -f $DIR/$tdir/$tfile
1896         exhaust_precreations 0 0x80000215
1897         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1898         touch $DIR/$tdir/$tfile || error "touch failed"
1899         $LFS getstripe $DIR/$tdir/$tfile
1900         reset_enospc
1901 }
1902 run_test 27n "create file with some full OSTs"
1903
1904 test_27o() {
1905         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1907         remote_mds_nodsh && skip "remote MDS with nodsh"
1908         remote_ost_nodsh && skip "remote OST with nodsh"
1909
1910         reset_enospc
1911         rm -f $DIR/$tdir/$tfile
1912         exhaust_all_precreations 0x215
1913
1914         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1915
1916         reset_enospc
1917         rm -rf $DIR/$tdir/*
1918 }
1919 run_test 27o "create file with all full OSTs (should error)"
1920
1921 function create_and_checktime() {
1922         local fname=$1
1923         local loops=$2
1924         local i
1925
1926         for ((i=0; i < $loops; i++)); do
1927                 local start=$SECONDS
1928                 multiop $fname-$i Oc
1929                 ((SECONDS-start < TIMEOUT)) ||
1930                         error "creation took " $((SECONDS-$start)) && return 1
1931         done
1932 }
1933
1934 test_27oo() {
1935         local mdts=$(comma_list $(mdts_nodes))
1936
1937         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1938                 skip "Need MDS version at least 2.13.57"
1939
1940         local f0=$DIR/${tfile}-0
1941         local f1=$DIR/${tfile}-1
1942
1943         wait_delete_completed
1944
1945         # refill precreated objects
1946         $LFS setstripe -i0 -c1 $f0
1947
1948         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1949         # force QoS allocation policy
1950         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1951         stack_trap "do_nodes $mdts $LCTL set_param \
1952                 lov.*.qos_threshold_rr=$saved" EXIT
1953         sleep_maxage
1954
1955         # one OST is unavailable, but still have few objects preallocated
1956         stop ost1
1957         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1958                 rm -rf $f1 $DIR/$tdir*" EXIT
1959
1960         for ((i=0; i < 7; i++)); do
1961                 mkdir $DIR/$tdir$i || error "can't create dir"
1962                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1963                         error "can't set striping"
1964         done
1965         for ((i=0; i < 7; i++)); do
1966                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1967         done
1968         wait
1969 }
1970 run_test 27oo "don't let few threads to reserve too many objects"
1971
1972 test_27p() {
1973         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1975         remote_mds_nodsh && skip "remote MDS with nodsh"
1976         remote_ost_nodsh && skip "remote OST with nodsh"
1977
1978         reset_enospc
1979         rm -f $DIR/$tdir/$tfile
1980         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1981
1982         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1983         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1984         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1985
1986         exhaust_precreations 0 0x80000215
1987         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1988         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1989         $LFS getstripe $DIR/$tdir/$tfile
1990
1991         reset_enospc
1992 }
1993 run_test 27p "append to a truncated file with some full OSTs"
1994
1995 test_27q() {
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         reset_enospc
2002         rm -f $DIR/$tdir/$tfile
2003
2004         mkdir_on_mdt0 $DIR/$tdir
2005         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2006         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2007                 error "truncate $DIR/$tdir/$tfile failed"
2008         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2009
2010         exhaust_all_precreations 0x215
2011
2012         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2013         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2014
2015         reset_enospc
2016 }
2017 run_test 27q "append to truncated file with all OSTs full (should error)"
2018
2019 test_27r() {
2020         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2022         remote_mds_nodsh && skip "remote MDS with nodsh"
2023         remote_ost_nodsh && skip "remote OST with nodsh"
2024
2025         reset_enospc
2026         rm -f $DIR/$tdir/$tfile
2027         exhaust_precreations 0 0x80000215
2028
2029         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2030
2031         reset_enospc
2032 }
2033 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2034
2035 test_27s() { # bug 10725
2036         test_mkdir $DIR/$tdir
2037         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2038         local stripe_count=0
2039         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2040         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2041                 error "stripe width >= 2^32 succeeded" || true
2042
2043 }
2044 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2045
2046 test_27t() { # bug 10864
2047         WDIR=$(pwd)
2048         WLFS=$(which lfs)
2049         cd $DIR
2050         touch $tfile
2051         $WLFS getstripe $tfile
2052         cd $WDIR
2053 }
2054 run_test 27t "check that utils parse path correctly"
2055
2056 test_27u() { # bug 4900
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         remote_mds_nodsh && skip "remote MDS with nodsh"
2059
2060         local index
2061         local list=$(comma_list $(mdts_nodes))
2062
2063 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2064         do_nodes $list $LCTL set_param fail_loc=0x139
2065         test_mkdir -p $DIR/$tdir
2066         stack_trap "simple_cleanup_common 1000"
2067         createmany -o $DIR/$tdir/$tfile 1000
2068         do_nodes $list $LCTL set_param fail_loc=0
2069
2070         TLOG=$TMP/$tfile.getstripe
2071         $LFS getstripe $DIR/$tdir > $TLOG
2072         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2073         [[ $OBJS -gt 0 ]] &&
2074                 error "$OBJS objects created on OST-0. See $TLOG" ||
2075                 rm -f $TLOG
2076 }
2077 run_test 27u "skip object creation on OSC w/o objects"
2078
2079 test_27v() { # bug 4900
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082         remote_mds_nodsh && skip "remote MDS with nodsh"
2083         remote_ost_nodsh && skip "remote OST with nodsh"
2084
2085         exhaust_all_precreations 0x215
2086         reset_enospc
2087
2088         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2089
2090         touch $DIR/$tdir/$tfile
2091         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2092         # all except ost1
2093         for (( i=1; i < OSTCOUNT; i++ )); do
2094                 do_facet ost$i lctl set_param fail_loc=0x705
2095         done
2096         local START=`date +%s`
2097         createmany -o $DIR/$tdir/$tfile 32
2098
2099         local FINISH=`date +%s`
2100         local TIMEOUT=`lctl get_param -n timeout`
2101         local PROCESS=$((FINISH - START))
2102         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2103                error "$FINISH - $START >= $TIMEOUT / 2"
2104         sleep $((TIMEOUT / 2 - PROCESS))
2105         reset_enospc
2106 }
2107 run_test 27v "skip object creation on slow OST"
2108
2109 test_27w() { # bug 10997
2110         test_mkdir $DIR/$tdir
2111         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2112         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2113                 error "stripe size $size != 65536" || true
2114         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2115                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2116 }
2117 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2118
2119 test_27wa() {
2120         [[ $OSTCOUNT -lt 2 ]] &&
2121                 skip_env "skipping multiple stripe count/offset test"
2122
2123         test_mkdir $DIR/$tdir
2124         for i in $(seq 1 $OSTCOUNT); do
2125                 offset=$((i - 1))
2126                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2127                         error "setstripe -c $i -i $offset failed"
2128                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2129                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2130                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2131                 [ $index -ne $offset ] &&
2132                         error "stripe offset $index != $offset" || true
2133         done
2134 }
2135 run_test 27wa "check $LFS setstripe -c -i options"
2136
2137 test_27x() {
2138         remote_ost_nodsh && skip "remote OST with nodsh"
2139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2141
2142         OFFSET=$(($OSTCOUNT - 1))
2143         OSTIDX=0
2144         local OST=$(ostname_from_index $OSTIDX)
2145
2146         test_mkdir $DIR/$tdir
2147         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2151         for i in $(seq 0 $OFFSET); do
2152                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2153                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2154                 error "OST0 was degraded but new created file still use it"
2155         done
2156         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2157 }
2158 run_test 27x "create files while OST0 is degraded"
2159
2160 test_27y() {
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         remote_mds_nodsh && skip "remote MDS with nodsh"
2163         remote_ost_nodsh && skip "remote OST with nodsh"
2164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2165
2166         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2167         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2168                 osp.$mdtosc.prealloc_last_id)
2169         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2170                 osp.$mdtosc.prealloc_next_id)
2171         local fcount=$((last_id - next_id))
2172         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2173         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2174
2175         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2176                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2177         local OST_DEACTIVE_IDX=-1
2178         local OSC
2179         local OSTIDX
2180         local OST
2181
2182         for OSC in $MDS_OSCS; do
2183                 OST=$(osc_to_ost $OSC)
2184                 OSTIDX=$(index_from_ostuuid $OST)
2185                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2186                         OST_DEACTIVE_IDX=$OSTIDX
2187                 fi
2188                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2189                         echo $OSC "is Deactivated:"
2190                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2191                 fi
2192         done
2193
2194         OSTIDX=$(index_from_ostuuid $OST)
2195         test_mkdir $DIR/$tdir
2196         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2197
2198         for OSC in $MDS_OSCS; do
2199                 OST=$(osc_to_ost $OSC)
2200                 OSTIDX=$(index_from_ostuuid $OST)
2201                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2202                         echo $OST "is degraded:"
2203                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2204                                                 obdfilter.$OST.degraded=1
2205                 fi
2206         done
2207
2208         sleep_maxage
2209         createmany -o $DIR/$tdir/$tfile $fcount
2210
2211         for OSC in $MDS_OSCS; do
2212                 OST=$(osc_to_ost $OSC)
2213                 OSTIDX=$(index_from_ostuuid $OST)
2214                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2215                         echo $OST "is recovered from degraded:"
2216                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2217                                                 obdfilter.$OST.degraded=0
2218                 else
2219                         do_facet $SINGLEMDS lctl --device %$OSC activate
2220                 fi
2221         done
2222
2223         # all osp devices get activated, hence -1 stripe count restored
2224         local stripe_count=0
2225
2226         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2227         # devices get activated.
2228         sleep_maxage
2229         $LFS setstripe -c -1 $DIR/$tfile
2230         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2231         rm -f $DIR/$tfile
2232         [ $stripe_count -ne $OSTCOUNT ] &&
2233                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2234         return 0
2235 }
2236 run_test 27y "create files while OST0 is degraded and the rest inactive"
2237
2238 check_seq_oid()
2239 {
2240         log "check file $1"
2241
2242         lmm_count=$($LFS getstripe -c $1)
2243         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2244         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2245
2246         local old_ifs="$IFS"
2247         IFS=$'[:]'
2248         fid=($($LFS path2fid $1))
2249         IFS="$old_ifs"
2250
2251         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2252         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2253
2254         # compare lmm_seq and lu_fid->f_seq
2255         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2256         # compare lmm_object_id and lu_fid->oid
2257         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2258
2259         # check the trusted.fid attribute of the OST objects of the file
2260         local have_obdidx=false
2261         local stripe_nr=0
2262         $LFS getstripe $1 | while read obdidx oid hex seq; do
2263                 # skip lines up to and including "obdidx"
2264                 [ -z "$obdidx" ] && break
2265                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2266                 $have_obdidx || continue
2267
2268                 local ost=$((obdidx + 1))
2269                 local dev=$(ostdevname $ost)
2270                 local oid_hex
2271
2272                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2273
2274                 seq=$(echo $seq | sed -e "s/^0x//g")
2275                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2276                         oid_hex=$(echo $oid)
2277                 else
2278                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2279                 fi
2280                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2281
2282                 local ff=""
2283                 #
2284                 # Don't unmount/remount the OSTs if we don't need to do that.
2285                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2286                 # update too, until that use mount/ll_decode_filter_fid/mount.
2287                 # Re-enable when debugfs will understand new filter_fid.
2288                 #
2289                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2290                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2291                                 $dev 2>/dev/null" | grep "parent=")
2292                 fi
2293                 if [ -z "$ff" ]; then
2294                         stop ost$ost
2295                         mount_fstype ost$ost
2296                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2297                                 $(facet_mntpt ost$ost)/$obj_file)
2298                         unmount_fstype ost$ost
2299                         start ost$ost $dev $OST_MOUNT_OPTS
2300                         clients_up
2301                 fi
2302
2303                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2304
2305                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2306
2307                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2308                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2309                 #
2310                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2311                 #       stripe_size=1048576 component_id=1 component_start=0 \
2312                 #       component_end=33554432
2313                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2314                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2315                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2316                 local ff_pstripe
2317                 if grep -q 'stripe=' <<<$ff; then
2318                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2319                 else
2320                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2321                         # into f_ver in this case.  See comment on ff_parent.
2322                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2323                 fi
2324
2325                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2326                 [ $ff_pseq = $lmm_seq ] ||
2327                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2328                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2329                 [ $ff_poid = $lmm_oid ] ||
2330                         error "FF parent OID $ff_poid != $lmm_oid"
2331                 (($ff_pstripe == $stripe_nr)) ||
2332                         error "FF stripe $ff_pstripe != $stripe_nr"
2333
2334                 stripe_nr=$((stripe_nr + 1))
2335                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2336                         continue
2337                 if grep -q 'stripe_count=' <<<$ff; then
2338                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2339                                             -e 's/ .*//' <<<$ff)
2340                         [ $lmm_count = $ff_scnt ] ||
2341                                 error "FF stripe count $lmm_count != $ff_scnt"
2342                 fi
2343         done
2344 }
2345
2346 test_27z() {
2347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2348         remote_ost_nodsh && skip "remote OST with nodsh"
2349
2350         test_mkdir $DIR/$tdir
2351         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2352                 { error "setstripe -c -1 failed"; return 1; }
2353         # We need to send a write to every object to get parent FID info set.
2354         # This _should_ also work for setattr, but does not currently.
2355         # touch $DIR/$tdir/$tfile-1 ||
2356         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2357                 { error "dd $tfile-1 failed"; return 2; }
2358         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2359                 { error "setstripe -c -1 failed"; return 3; }
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2361                 { error "dd $tfile-2 failed"; return 4; }
2362
2363         # make sure write RPCs have been sent to OSTs
2364         sync; sleep 5; sync
2365
2366         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2367         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2368 }
2369 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2370
2371 test_27A() { # b=19102
2372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2373
2374         save_layout_restore_at_exit $MOUNT
2375         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2376         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2377                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2378         local default_size=$($LFS getstripe -S $MOUNT)
2379         local default_offset=$($LFS getstripe -i $MOUNT)
2380         local dsize=$(do_facet $SINGLEMDS \
2381                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2382         [ $default_size -eq $dsize ] ||
2383                 error "stripe size $default_size != $dsize"
2384         [ $default_offset -eq -1 ] ||
2385                 error "stripe offset $default_offset != -1"
2386 }
2387 run_test 27A "check filesystem-wide default LOV EA values"
2388
2389 test_27B() { # LU-2523
2390         test_mkdir $DIR/$tdir
2391         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2392         touch $DIR/$tdir/f0
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # rename f0 onto f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2398                 $DIR/$tdir/f0
2399
2400         rm -f $DIR/$tdir/f1
2401         # open f1 with O_LOV_DELAY_CREATE
2402         # unlink f1
2403         # call setstripe ioctl on open file descriptor for f1
2404         # close
2405         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2406
2407         # Allow multiop to fail in imitation of NFS's busted semantics.
2408         true
2409 }
2410 run_test 27B "call setstripe on open unlinked file/rename victim"
2411
2412 # 27C family tests full striping and overstriping
2413 test_27Ca() { #LU-2871
2414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2415
2416         declare -a ost_idx
2417         local index
2418         local found
2419         local i
2420         local j
2421
2422         test_mkdir $DIR/$tdir
2423         cd $DIR/$tdir
2424         for i in $(seq 0 $((OSTCOUNT - 1))); do
2425                 # set stripe across all OSTs starting from OST$i
2426                 $LFS setstripe -i $i -c -1 $tfile$i
2427                 # get striping information
2428                 ost_idx=($($LFS getstripe $tfile$i |
2429                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2430                 echo "OST Index: ${ost_idx[*]}"
2431
2432                 # check the layout
2433                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2434                         error "${#ost_idx[@]} != $OSTCOUNT"
2435
2436                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2437                         found=0
2438                         for j in "${ost_idx[@]}"; do
2439                                 if [ $index -eq $j ]; then
2440                                         found=1
2441                                         break
2442                                 fi
2443                         done
2444                         [ $found = 1 ] ||
2445                                 error "Can not find $index in ${ost_idx[*]}"
2446                 done
2447         done
2448 }
2449 run_test 27Ca "check full striping across all OSTs"
2450
2451 test_27Cb() {
2452         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2453                 skip "server does not support overstriping"
2454         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2455                 skip_env "too many osts, skipping"
2456
2457         test_mkdir -p $DIR/$tdir
2458         local setcount=$(($OSTCOUNT * 2))
2459         [ $setcount -lt 160 ] || large_xattr_enabled ||
2460                 skip_env "ea_inode feature disabled"
2461
2462         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2463                 error "setstripe failed"
2464
2465         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2466         [ $count -eq $setcount ] ||
2467                 error "stripe count $count, should be $setcount"
2468
2469         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2470                 error "overstriped should be set in pattern"
2471
2472         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2473                 error "dd failed"
2474 }
2475 run_test 27Cb "more stripes than OSTs with -C"
2476
2477 test_27Cc() {
2478         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2479                 skip "server does not support overstriping"
2480         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2481
2482         test_mkdir -p $DIR/$tdir
2483         local setcount=$(($OSTCOUNT - 1))
2484
2485         [ $setcount -lt 160 ] || large_xattr_enabled ||
2486                 skip_env "ea_inode feature disabled"
2487
2488         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2489                 error "setstripe failed"
2490
2491         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2492         [ $count -eq $setcount ] ||
2493                 error "stripe count $count, should be $setcount"
2494
2495         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2496                 error "overstriped should not be set in pattern"
2497
2498         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2499                 error "dd failed"
2500 }
2501 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2502
2503 test_27Cd() {
2504         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2505                 skip "server does not support overstriping"
2506         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2507         large_xattr_enabled || skip_env "ea_inode feature disabled"
2508
2509         force_new_seq_all
2510
2511         test_mkdir -p $DIR/$tdir
2512         local setcount=$LOV_MAX_STRIPE_COUNT
2513
2514         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2515                 error "setstripe failed"
2516
2517         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2518         [ $count -eq $setcount ] ||
2519                 error "stripe count $count, should be $setcount"
2520
2521         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2522                 error "overstriped should be set in pattern"
2523
2524         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2525                 error "dd failed"
2526
2527         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2528 }
2529 run_test 27Cd "test maximum stripe count"
2530
2531 test_27Ce() {
2532         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2533                 skip "server does not support overstriping"
2534         test_mkdir -p $DIR/$tdir
2535
2536         pool_add $TESTNAME || error "Pool creation failed"
2537         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2538
2539         local setcount=8
2540
2541         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2542                 error "setstripe failed"
2543
2544         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2545         [ $count -eq $setcount ] ||
2546                 error "stripe count $count, should be $setcount"
2547
2548         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2549                 error "overstriped should be set in pattern"
2550
2551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2552                 error "dd failed"
2553
2554         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2555 }
2556 run_test 27Ce "test pool with overstriping"
2557
2558 test_27Cf() {
2559         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2560                 skip "server does not support overstriping"
2561         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2562                 skip_env "too many osts, skipping"
2563
2564         test_mkdir -p $DIR/$tdir
2565
2566         local setcount=$(($OSTCOUNT * 2))
2567         [ $setcount -lt 160 ] || large_xattr_enabled ||
2568                 skip_env "ea_inode feature disabled"
2569
2570         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2571                 error "setstripe failed"
2572
2573         echo 1 > $DIR/$tdir/$tfile
2574
2575         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2576         [ $count -eq $setcount ] ||
2577                 error "stripe count $count, should be $setcount"
2578
2579         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2580                 error "overstriped should be set in pattern"
2581
2582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2583                 error "dd failed"
2584
2585         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2586 }
2587 run_test 27Cf "test default inheritance with overstriping"
2588
2589 test_27Cg() {
2590         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2591                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2592
2593         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2594         (( $? != 0 )) || error "must be an error for not existent OST#"
2595 }
2596 run_test 27Cg "test setstripe with wrong OST idx"
2597
2598 test_27Ci() {
2599         local tf=$DIR/$tfile
2600
2601         stack_trap "rm -f $DIR/$tfile"
2602
2603         $LFS setstripe -E1M $tf || error "create $tf failed"
2604         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2605                 error "add component failed"
2606
2607         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2608                 grep "overstriped" || {
2609                 $LFS getstripe $tf
2610                 echo "lose overstriping setting"
2611         }
2612         sc=$($LFS getstripe -I2 --stripe-count $tf)
2613         (( $sc == 100 )) || {
2614                 $LFS getstripe $tf
2615                 echo "lose overstriping setting"
2616         }
2617
2618         stack_trap "rm -f $tf"
2619         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2620         sc=$($LFS getstripe -I2 --stripe-count $tf)
2621         (( $sc == 100 )) || {
2622                 $LFS getstripe $tf
2623                 echo "lose overstriping setting after instantiation"
2624         }
2625 }
2626 run_test 27Ci "add an overstriping component"
2627
2628 test_27D() {
2629         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2630         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2631         remote_mds_nodsh && skip "remote MDS with nodsh"
2632
2633         local POOL=${POOL:-testpool}
2634         local first_ost=0
2635         local last_ost=$(($OSTCOUNT - 1))
2636         local ost_step=1
2637         local ost_list=$(seq $first_ost $ost_step $last_ost)
2638         local ost_range="$first_ost $last_ost $ost_step"
2639
2640         test_mkdir $DIR/$tdir
2641         pool_add $POOL || error "pool_add failed"
2642         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2643
2644         local skip27D
2645         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2646                 skip27D+="-s 29"
2647         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2648                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2649                         skip27D+=" -s 30,31"
2650         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2651           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2652                 skip27D+=" -s 32,33"
2653         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2654                 skip27D+=" -s 34"
2655         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2656                 error "llapi_layout_test failed"
2657
2658         destroy_test_pools || error "destroy test pools failed"
2659 }
2660 run_test 27D "validate llapi_layout API"
2661
2662 # Verify that default_easize is increased from its initial value after
2663 # accessing a widely striped file.
2664 test_27E() {
2665         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2666         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2667                 skip "client does not have LU-3338 fix"
2668
2669         # 72 bytes is the minimum space required to store striping
2670         # information for a file striped across one OST:
2671         # (sizeof(struct lov_user_md_v3) +
2672         #  sizeof(struct lov_user_ost_data_v1))
2673         local min_easize=72
2674         $LCTL set_param -n llite.*.default_easize $min_easize ||
2675                 error "lctl set_param failed"
2676         local easize=$($LCTL get_param -n llite.*.default_easize)
2677
2678         [ $easize -eq $min_easize ] ||
2679                 error "failed to set default_easize"
2680
2681         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2682                 error "setstripe failed"
2683         # In order to ensure stat() call actually talks to MDS we need to
2684         # do something drastic to this file to shake off all lock, e.g.
2685         # rename it (kills lookup lock forcing cache cleaning)
2686         mv $DIR/$tfile $DIR/${tfile}-1
2687         ls -l $DIR/${tfile}-1
2688         rm $DIR/${tfile}-1
2689
2690         easize=$($LCTL get_param -n llite.*.default_easize)
2691
2692         [ $easize -gt $min_easize ] ||
2693                 error "default_easize not updated"
2694 }
2695 run_test 27E "check that default extended attribute size properly increases"
2696
2697 test_27F() { # LU-5346/LU-7975
2698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2699         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2700         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2701                 skip "Need MDS version at least 2.8.51"
2702         remote_ost_nodsh && skip "remote OST with nodsh"
2703
2704         test_mkdir $DIR/$tdir
2705         rm -f $DIR/$tdir/f0
2706         $LFS setstripe -c 2 $DIR/$tdir
2707
2708         # stop all OSTs to reproduce situation for LU-7975 ticket
2709         for num in $(seq $OSTCOUNT); do
2710                 stop ost$num
2711         done
2712
2713         # open/create f0 with O_LOV_DELAY_CREATE
2714         # truncate f0 to a non-0 size
2715         # close
2716         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2717
2718         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2719         # open/write it again to force delayed layout creation
2720         cat /etc/hosts > $DIR/$tdir/f0 &
2721         catpid=$!
2722
2723         # restart OSTs
2724         for num in $(seq $OSTCOUNT); do
2725                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2726                         error "ost$num failed to start"
2727         done
2728
2729         wait $catpid || error "cat failed"
2730
2731         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2732         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2733                 error "wrong stripecount"
2734
2735 }
2736 run_test 27F "Client resend delayed layout creation with non-zero size"
2737
2738 test_27G() { #LU-10629
2739         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2740                 skip "Need MDS version at least 2.11.51"
2741         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2742         remote_mds_nodsh && skip "remote MDS with nodsh"
2743         local POOL=${POOL:-testpool}
2744         local ostrange="0 0 1"
2745
2746         test_mkdir $DIR/$tdir
2747         touch $DIR/$tdir/$tfile.nopool
2748         pool_add $POOL || error "pool_add failed"
2749         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2750         $LFS setstripe -p $POOL $DIR/$tdir
2751
2752         local pool=$($LFS getstripe -p $DIR/$tdir)
2753
2754         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2755         touch $DIR/$tdir/$tfile.default
2756         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2757         $LFS find $DIR/$tdir -type f --pool $POOL
2758         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2759         [[ "$found" == "2" ]] ||
2760                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2761
2762         $LFS setstripe -d $DIR/$tdir
2763
2764         pool=$($LFS getstripe -p -d $DIR/$tdir)
2765
2766         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2767 }
2768 run_test 27G "Clear OST pool from stripe"
2769
2770 test_27H() {
2771         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2772                 skip "Need MDS version newer than 2.11.54"
2773         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2774         test_mkdir $DIR/$tdir
2775         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2776         touch $DIR/$tdir/$tfile
2777         $LFS getstripe -c $DIR/$tdir/$tfile
2778         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2779                 error "two-stripe file doesn't have two stripes"
2780
2781         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2782         $LFS getstripe -y $DIR/$tdir/$tfile
2783         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2784              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2785                 error "expected l_ost_idx: [02]$ not matched"
2786
2787         # make sure ost list has been cleared
2788         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2789         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2790                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2791         touch $DIR/$tdir/f3
2792         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2793 }
2794 run_test 27H "Set specific OSTs stripe"
2795
2796 test_27I() {
2797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2798         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2799         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2800                 skip "Need MDS version newer than 2.12.52"
2801         local pool=$TESTNAME
2802         local ostrange="1 1 1"
2803
2804         save_layout_restore_at_exit $MOUNT
2805         $LFS setstripe -c 2 -i 0 $MOUNT
2806         pool_add $pool || error "pool_add failed"
2807         pool_add_targets $pool $ostrange ||
2808                 error "pool_add_targets failed"
2809         test_mkdir $DIR/$tdir
2810         $LFS setstripe -p $pool $DIR/$tdir
2811         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2812         $LFS getstripe $DIR/$tdir/$tfile
2813 }
2814 run_test 27I "check that root dir striping does not break parent dir one"
2815
2816 test_27J() {
2817         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2818                 skip "Need MDS version newer than 2.12.51"
2819
2820         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2821         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2822         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2823            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2824                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2825
2826         test_mkdir $DIR/$tdir
2827         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2828         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2829
2830         # create foreign file (raw way)
2831         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2832                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2833
2834         ! $LFS setstripe --foreign --flags foo \
2835                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2836                         error "creating $tfile with '--flags foo' should fail"
2837
2838         ! $LFS setstripe --foreign --flags 0xffffffff \
2839                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2840                         error "creating $tfile w/ 0xffffffff flags should fail"
2841
2842         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2843                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2844
2845         # verify foreign file (raw way)
2846         parse_foreign_file -f $DIR/$tdir/$tfile |
2847                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2848                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2849         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2850                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2851         parse_foreign_file -f $DIR/$tdir/$tfile |
2852                 grep "lov_foreign_size: 73" ||
2853                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2854         parse_foreign_file -f $DIR/$tdir/$tfile |
2855                 grep "lov_foreign_type: 1" ||
2856                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2857         parse_foreign_file -f $DIR/$tdir/$tfile |
2858                 grep "lov_foreign_flags: 0x0000DA08" ||
2859                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2860         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2861                 grep "lov_foreign_value: 0x" |
2862                 sed -e 's/lov_foreign_value: 0x//')
2863         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2864         [[ $lov = ${lov2// /} ]] ||
2865                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2866
2867         # create foreign file (lfs + API)
2868         $LFS setstripe --foreign=none --flags 0xda08 \
2869                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2870                 error "$DIR/$tdir/${tfile}2: create failed"
2871
2872         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2873                 grep "lfm_magic:.*0x0BD70BD0" ||
2874                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2875         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2876         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2877                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2878         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2879                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2880         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2881                 grep "lfm_flags:.*0x0000DA08" ||
2882                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2883         $LFS getstripe $DIR/$tdir/${tfile}2 |
2884                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2885                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2886
2887         # modify striping should fail
2888         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2889                 error "$DIR/$tdir/$tfile: setstripe should fail"
2890         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2891                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2892
2893         # R/W should fail
2894         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2895         cat $DIR/$tdir/${tfile}2 &&
2896                 error "$DIR/$tdir/${tfile}2: read should fail"
2897         cat /etc/passwd > $DIR/$tdir/$tfile &&
2898                 error "$DIR/$tdir/$tfile: write should fail"
2899         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2900                 error "$DIR/$tdir/${tfile}2: write should fail"
2901
2902         # chmod should work
2903         chmod 222 $DIR/$tdir/$tfile ||
2904                 error "$DIR/$tdir/$tfile: chmod failed"
2905         chmod 222 $DIR/$tdir/${tfile}2 ||
2906                 error "$DIR/$tdir/${tfile}2: chmod failed"
2907
2908         # chown should work
2909         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2910                 error "$DIR/$tdir/$tfile: chown failed"
2911         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2912                 error "$DIR/$tdir/${tfile}2: chown failed"
2913
2914         # rename should work
2915         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2916                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2917         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2918                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2919
2920         #remove foreign file
2921         rm $DIR/$tdir/${tfile}.new ||
2922                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2923         rm $DIR/$tdir/${tfile}2.new ||
2924                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2925 }
2926 run_test 27J "basic ops on file with foreign LOV"
2927
2928 test_27K() {
2929         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2930                 skip "Need MDS version newer than 2.12.49"
2931
2932         test_mkdir $DIR/$tdir
2933         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2934         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2935
2936         # create foreign dir (raw way)
2937         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2938                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2939
2940         ! $LFS setdirstripe --foreign --flags foo \
2941                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2942                         error "creating $tdir with '--flags foo' should fail"
2943
2944         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2945                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2946                         error "creating $tdir w/ 0xffffffff flags should fail"
2947
2948         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2949                 error "create_foreign_dir FAILED"
2950
2951         # verify foreign dir (raw way)
2952         parse_foreign_dir -d $DIR/$tdir/$tdir |
2953                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2954                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2955         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2956                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2957         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2958                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2959         parse_foreign_dir -d $DIR/$tdir/$tdir |
2960                 grep "lmv_foreign_flags: 55813$" ||
2961                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2962         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2963                 grep "lmv_foreign_value: 0x" |
2964                 sed 's/lmv_foreign_value: 0x//')
2965         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2966                 sed 's/ //g')
2967         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2968
2969         # create foreign dir (lfs + API)
2970         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2971                 $DIR/$tdir/${tdir}2 ||
2972                 error "$DIR/$tdir/${tdir}2: create failed"
2973
2974         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2975
2976         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2977                 grep "lfm_magic:.*0x0CD50CD0" ||
2978                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2979         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2980         # - sizeof(lfm_type) - sizeof(lfm_flags)
2981         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2982                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2983         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2984                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2985         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2986                 grep "lfm_flags:.*0x0000DA05" ||
2987                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2988         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2989                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2990                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2991
2992         # file create in dir should fail
2993         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2994         touch $DIR/$tdir/${tdir}2/$tfile &&
2995                 error "$DIR/${tdir}2: file create should fail"
2996
2997         # chmod should work
2998         chmod 777 $DIR/$tdir/$tdir ||
2999                 error "$DIR/$tdir: chmod failed"
3000         chmod 777 $DIR/$tdir/${tdir}2 ||
3001                 error "$DIR/${tdir}2: chmod failed"
3002
3003         # chown should work
3004         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3005                 error "$DIR/$tdir: chown failed"
3006         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3007                 error "$DIR/${tdir}2: chown failed"
3008
3009         # rename should work
3010         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3011                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3012         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3013                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3014
3015         #remove foreign dir
3016         rmdir $DIR/$tdir/${tdir}.new ||
3017                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3018         rmdir $DIR/$tdir/${tdir}2.new ||
3019                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3020 }
3021 run_test 27K "basic ops on dir with foreign LMV"
3022
3023 test_27L() {
3024         remote_mds_nodsh && skip "remote MDS with nodsh"
3025
3026         local POOL=${POOL:-$TESTNAME}
3027
3028         pool_add $POOL || error "pool_add failed"
3029
3030         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3031                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3032                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3033 }
3034 run_test 27L "lfs pool_list gives correct pool name"
3035
3036 test_27M() {
3037         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3038                 skip "Need MDS version >= than 2.12.57"
3039         remote_mds_nodsh && skip "remote MDS with nodsh"
3040         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3041
3042         # Set default striping on directory
3043         local setcount=4
3044         local stripe_opt
3045         local mdts=$(comma_list $(mdts_nodes))
3046
3047         # if we run against a 2.12 server which lacks overstring support
3048         # then the connect_flag will not report overstriping, even if client
3049         # is 2.14+
3050         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3051                 stripe_opt="-C $setcount"
3052         elif (( $OSTCOUNT >= $setcount )); then
3053                 stripe_opt="-c $setcount"
3054         else
3055                 skip "server does not support overstriping"
3056         fi
3057
3058         test_mkdir $DIR/$tdir
3059
3060         # Validate existing append_* params and ensure restore
3061         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3062         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3063         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3064
3065         # Validate append_pool name length
3066         (( $MDS1_VERSION >= $(version_code 2.15.61) )) &&
3067                 do_nodes $mdts $LCTL \
3068                         set_param mdd.*.append_pool="LOV_MAXPOOLNAME*" &&
3069                         error "Wrong pool name length should report error"
3070
3071         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3072         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3073         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3074
3075         $LFS setstripe $stripe_opt $DIR/$tdir
3076
3077         echo 1 > $DIR/$tdir/${tfile}.1
3078         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3079         (( $count == $setcount )) ||
3080                 error "(1) stripe count $count, should be $setcount"
3081
3082         local appendcount=$orig_count
3083         echo 1 >> $DIR/$tdir/${tfile}.2_append
3084         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3085         (( $count == $appendcount )) ||
3086                 error "(2)stripe count $count, should be $appendcount for append"
3087
3088         # Disable O_APPEND striping, verify it works
3089         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3090
3091         # Should now get the default striping, which is 4
3092         setcount=4
3093         echo 1 >> $DIR/$tdir/${tfile}.3_append
3094         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3095         (( $count == $setcount )) ||
3096                 error "(3) stripe count $count, should be $setcount"
3097
3098         # Try changing the stripe count for append files
3099         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3100
3101         # Append striping is now 2 (directory default is still 4)
3102         appendcount=2
3103         echo 1 >> $DIR/$tdir/${tfile}.4_append
3104         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3105         (( $count == $appendcount )) ||
3106                 error "(4) stripe count $count, should be $appendcount for append"
3107
3108         # Test append stripe count of -1
3109         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3110         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3111                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3112                 touch $DIR/$tdir/$tfile.specific.{1..128}
3113         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3114
3115         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3116         appendcount=$OSTCOUNT
3117         echo 1 >> $DIR/$tdir/${tfile}.5
3118         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3119         (( $count == $appendcount )) ||
3120                 error "(5) stripe count $count, should be $appendcount for append"
3121
3122         # Set append striping back to default of 1
3123         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3124
3125         # Try a new default striping, PFL + DOM
3126         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3127
3128         # Create normal DOM file, DOM returns stripe count == 0
3129         setcount=0
3130         touch $DIR/$tdir/${tfile}.6
3131         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3132         (( $count == $setcount )) ||
3133                 error "(6) stripe count $count, should be $setcount"
3134
3135         # Show
3136         appendcount=1
3137         echo 1 >> $DIR/$tdir/${tfile}.7_append
3138         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3139         (( $count == $appendcount )) ||
3140                 error "(7) stripe count $count, should be $appendcount for append"
3141
3142         # Clean up DOM layout
3143         $LFS setstripe -d $DIR/$tdir
3144
3145         save_layout_restore_at_exit $MOUNT
3146         # Now test that append striping works when layout is from root
3147         $LFS setstripe -c 2 $MOUNT
3148         # Make a special directory for this
3149         mkdir $DIR/${tdir}/${tdir}.2
3150
3151         # Verify for normal file
3152         setcount=2
3153         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3154         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3155         (( $count == $setcount )) ||
3156                 error "(8) stripe count $count, should be $setcount"
3157
3158         appendcount=1
3159         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3160         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3161         (( $count == $appendcount )) ||
3162                 error "(9) stripe count $count, should be $appendcount for append"
3163
3164         # Now test O_APPEND striping with pools
3165         pool_add $TESTNAME || error "pool creation failed"
3166         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3167         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3168
3169         echo 1 >> $DIR/$tdir/${tfile}.10_append
3170
3171         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3172         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3173
3174         # Check that count is still correct
3175         appendcount=1
3176         echo 1 >> $DIR/$tdir/${tfile}.11_append
3177         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3178         (( $count == $appendcount )) ||
3179                 error "(11) stripe count $count, should be $appendcount for append"
3180
3181         # Disable O_APPEND stripe count, verify pool works separately
3182         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3183
3184         echo 1 >> $DIR/$tdir/${tfile}.12_append
3185
3186         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3187         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3188
3189         # Remove pool setting, verify it's not applied
3190         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3191
3192         echo 1 >> $DIR/$tdir/${tfile}.13_append
3193
3194         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3195         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3196 }
3197 run_test 27M "test O_APPEND striping"
3198
3199 test_27N() {
3200         combined_mgs_mds && skip "needs separate MGS/MDT"
3201
3202         pool_add $TESTNAME || error "pool_add failed"
3203         do_facet mgs "$LCTL pool_list $FSNAME" |
3204                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3205                 error "lctl pool_list on MGS failed"
3206 }
3207 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3208
3209 clean_foreign_symlink() {
3210         trap 0
3211         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3212         for i in $DIR/$tdir/* ; do
3213                 $LFS unlink_foreign $i || true
3214         done
3215 }
3216
3217 test_27O() {
3218         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3219                 skip "Need MDS version newer than 2.12.51"
3220
3221         test_mkdir $DIR/$tdir
3222         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3223         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3224
3225         trap clean_foreign_symlink EXIT
3226
3227         # enable foreign_symlink behaviour
3228         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3229
3230         # foreign symlink LOV format is a partial path by default
3231
3232         # create foreign file (lfs + API)
3233         $LFS setstripe --foreign=symlink --flags 0xda05 \
3234                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3235                 error "$DIR/$tdir/${tfile}: create failed"
3236
3237         $LFS getstripe -v $DIR/$tdir/${tfile} |
3238                 grep "lfm_magic:.*0x0BD70BD0" ||
3239                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3240         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3241                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3242         $LFS getstripe -v $DIR/$tdir/${tfile} |
3243                 grep "lfm_flags:.*0x0000DA05" ||
3244                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3245         $LFS getstripe $DIR/$tdir/${tfile} |
3246                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3247                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3248
3249         # modify striping should fail
3250         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3251                 error "$DIR/$tdir/$tfile: setstripe should fail"
3252
3253         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3254         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3255         cat /etc/passwd > $DIR/$tdir/$tfile &&
3256                 error "$DIR/$tdir/$tfile: write should fail"
3257
3258         # rename should succeed
3259         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3260                 error "$DIR/$tdir/$tfile: rename has failed"
3261
3262         #remove foreign_symlink file should fail
3263         rm $DIR/$tdir/${tfile}.new &&
3264                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3265
3266         #test fake symlink
3267         mkdir /tmp/${uuid1} ||
3268                 error "/tmp/${uuid1}: mkdir has failed"
3269         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3270                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3271         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3272         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3273                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3274         #read should succeed now
3275         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3276                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3277         #write should succeed now
3278         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3279                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3280         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3281                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3282         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3283                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3284
3285         #check that getstripe still works
3286         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3287                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3288
3289         # chmod should still succeed
3290         chmod 644 $DIR/$tdir/${tfile}.new ||
3291                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3292
3293         # chown should still succeed
3294         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3295                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3296
3297         # rename should still succeed
3298         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3299                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3300
3301         #remove foreign_symlink file should still fail
3302         rm $DIR/$tdir/${tfile} &&
3303                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3304
3305         #use special ioctl() to unlink foreign_symlink file
3306         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3307                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3308
3309 }
3310 run_test 27O "basic ops on foreign file of symlink type"
3311
3312 test_27P() {
3313         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3314                 skip "Need MDS version newer than 2.12.49"
3315
3316         test_mkdir $DIR/$tdir
3317         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3318         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3319
3320         trap clean_foreign_symlink EXIT
3321
3322         # enable foreign_symlink behaviour
3323         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3324
3325         # foreign symlink LMV format is a partial path by default
3326
3327         # create foreign dir (lfs + API)
3328         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3329                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3330                 error "$DIR/$tdir/${tdir}: create failed"
3331
3332         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3333
3334         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3335                 grep "lfm_magic:.*0x0CD50CD0" ||
3336                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3337         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3338                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3339         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3340                 grep "lfm_flags:.*0x0000DA05" ||
3341                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3342         $LFS getdirstripe $DIR/$tdir/${tdir} |
3343                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3344                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3345
3346         # file create in dir should fail
3347         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3348         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3349
3350         # rename should succeed
3351         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3352                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3353
3354         #remove foreign_symlink dir should fail
3355         rmdir $DIR/$tdir/${tdir}.new &&
3356                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3357
3358         #test fake symlink
3359         mkdir -p /tmp/${uuid1}/${uuid2} ||
3360                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3361         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3362                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3363         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3364         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3365                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3366         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3367                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3368
3369         #check that getstripe fails now that foreign_symlink enabled
3370         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3371                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3372
3373         # file create in dir should work now
3374         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3375                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3376         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3377                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3378         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3379                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3380
3381         # chmod should still succeed
3382         chmod 755 $DIR/$tdir/${tdir}.new ||
3383                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3384
3385         # chown should still succeed
3386         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3387                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3388
3389         # rename should still succeed
3390         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3391                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3392
3393         #remove foreign_symlink dir should still fail
3394         rmdir $DIR/$tdir/${tdir} &&
3395                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3396
3397         #use special ioctl() to unlink foreign_symlink file
3398         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3399                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3400
3401         #created file should still exist
3402         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3403                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3404         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3405                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3406 }
3407 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3408
3409 test_27Q() {
3410         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3411         stack_trap "rm -f $TMP/$tfile*"
3412
3413         test_mkdir $DIR/$tdir-1
3414         test_mkdir $DIR/$tdir-2
3415
3416         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3417         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3418
3419         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3420         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3421
3422         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3423         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3424
3425         # Create some bad symlinks and ensure that we don't loop
3426         # forever or something. These should return ELOOP (40) and
3427         # ENOENT (2) but I don't want to test for that because there's
3428         # always some weirdo architecture that needs to ruin
3429         # everything by defining these error numbers differently.
3430
3431         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3432         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3433
3434         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3435         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3436
3437         return 0
3438 }
3439 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3440
3441 test_27R() {
3442         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3443                 skip "need MDS 2.14.55 or later"
3444         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3445
3446         local testdir="$DIR/$tdir"
3447         test_mkdir -p $testdir
3448         stack_trap "rm -rf $testdir"
3449         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3450
3451         local f1="$testdir/f1"
3452         touch $f1 || error "failed to touch $f1"
3453         local count=$($LFS getstripe -c $f1)
3454         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3455
3456         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3457         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3458
3459         local maxcount=$(($OSTCOUNT - 1))
3460         local mdts=$(comma_list $(mdts_nodes))
3461         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3462         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3463
3464         local f2="$testdir/f2"
3465         touch $f2 || error "failed to touch $f2"
3466         local count=$($LFS getstripe -c $f2)
3467         (( $count == $maxcount )) || error "wrong stripe count"
3468 }
3469 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3470
3471 test_27T() {
3472         [ $(facet_host client) == $(facet_host ost1) ] &&
3473                 skip "need ost1 and client on different nodes"
3474
3475 #define OBD_FAIL_OSC_NO_GRANT            0x411
3476         $LCTL set_param fail_loc=0x20000411 fail_val=1
3477 #define OBD_FAIL_OST_ENOSPC              0x215
3478         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3479         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3480         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3481                 error "multiop failed"
3482 }
3483 run_test 27T "no eio on close on partial write due to enosp"
3484
3485 test_27U() {
3486         local dir=$DIR/$tdir
3487         local file=$dir/$tfile
3488         local append_pool=${TESTNAME}-append
3489         local normal_pool=${TESTNAME}-normal
3490         local pool
3491         local stripe_count
3492         local stripe_count2
3493         local mdts=$(comma_list $(mdts_nodes))
3494
3495         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3496                 skip "Need MDS version at least 2.15.51 for append pool feature"
3497
3498         # Validate existing append_* params and ensure restore
3499         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3500         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3501         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3502
3503         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3504         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3505         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3506
3507         pool_add $append_pool || error "pool creation failed"
3508         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3509
3510         pool_add $normal_pool || error "pool creation failed"
3511         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3512
3513         test_mkdir $dir
3514         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3515
3516         echo XXX >> $file.1
3517         $LFS getstripe $file.1
3518
3519         pool=$($LFS getstripe -p $file.1)
3520         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3521
3522         stripe_count2=$($LFS getstripe -c $file.1)
3523         ((stripe_count2 == stripe_count)) ||
3524                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3525
3526         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3527
3528         echo XXX >> $file.2
3529         $LFS getstripe $file.2
3530
3531         pool=$($LFS getstripe -p $file.2)
3532         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3533
3534         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3535
3536         echo XXX >> $file.3
3537         $LFS getstripe $file.3
3538
3539         stripe_count2=$($LFS getstripe -c $file.3)
3540         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3541 }
3542 run_test 27U "append pool and stripe count work with composite default layout"
3543
3544 test_27V() {
3545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3546         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3547
3548         local dir=$DIR/$tdir
3549         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3550         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3551         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3552         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3553         local pid
3554
3555         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3556
3557         do_facet mds1 $LCTL set_param $lod_param=0
3558         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3559
3560         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3561         stack_trap "rm -rf $dir"
3562
3563         # exercise race in LU-16981 with deactivating OST while creating a file
3564         (
3565                 while true; do
3566                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3567                         sleep 0.1
3568                         do_facet mds1 \
3569                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3570                 done
3571         ) &
3572
3573         pid=$!
3574         stack_trap "kill -9 $pid"
3575
3576         # errors here are OK so ignore them (just don't want to crash)
3577         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3578
3579         return 0
3580 }
3581 run_test 27V "creating widely striped file races with deactivating OST"
3582
3583 # createtest also checks that device nodes are created and
3584 # then visible correctly (#2091)
3585 test_28() { # bug 2091
3586         test_mkdir $DIR/d28
3587         $CREATETEST $DIR/d28/ct || error "createtest failed"
3588 }
3589 run_test 28 "create/mknod/mkdir with bad file types ============"
3590
3591 test_29() {
3592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3593
3594         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3595                 disable_opencache
3596                 stack_trap "restore_opencache"
3597         }
3598
3599         sync; sleep 1; sync # flush out any dirty pages from previous tests
3600         cancel_lru_locks
3601         test_mkdir $DIR/d29
3602         touch $DIR/d29/foo
3603         log 'first d29'
3604         ls -l $DIR/d29
3605
3606         local locks_orig=$(total_used_locks mdc)
3607         (( $locks_orig != 0 )) || error "No mdc lock count"
3608
3609         local locks_unused_orig=$(total_unused_locks mdc)
3610
3611         log 'second d29'
3612         ls -l $DIR/d29
3613         log 'done'
3614
3615         local locks_current=$(total_used_locks mdc)
3616
3617         local locks_unused_current=$(total_unused_locks mdc)
3618
3619         if (( $locks_current > $locks_orig )); then
3620                 $LCTL set_param -n ldlm.dump_namespaces ""
3621                 error "CURRENT: $locks_current > $locks_orig"
3622         fi
3623         if (( $locks_unused_current > $locks_unused_orig )); then
3624                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3625         fi
3626 }
3627 run_test 29 "IT_GETATTR regression  ============================"
3628
3629 test_30a() { # was test_30
3630         cp $(which ls) $DIR || cp /bin/ls $DIR
3631         $DIR/ls / || error "Can't execute binary from lustre"
3632         rm $DIR/ls
3633 }
3634 run_test 30a "execute binary from Lustre (execve) =============="
3635
3636 test_30b() {
3637         cp `which ls` $DIR || cp /bin/ls $DIR
3638         chmod go+rx $DIR/ls
3639         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3640         rm $DIR/ls
3641 }
3642 run_test 30b "execute binary from Lustre as non-root ==========="
3643
3644 test_30c() { # b=22376
3645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3646
3647         cp $(which ls) $DIR || cp /bin/ls $DIR
3648         chmod a-rw $DIR/ls
3649         cancel_lru_locks mdc
3650         cancel_lru_locks osc
3651         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3652         rm -f $DIR/ls
3653 }
3654 run_test 30c "execute binary from Lustre without read perms ===="
3655
3656 test_30d() {
3657         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3658
3659         for i in {1..10}; do
3660                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3661                 local PID=$!
3662                 sleep 1
3663                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3664                 wait $PID || error "executing dd from Lustre failed"
3665                 rm -f $DIR/$tfile
3666         done
3667
3668         rm -f $DIR/dd
3669 }
3670 run_test 30d "execute binary from Lustre while clear locks"
3671
3672 test_31a() {
3673         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3674         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3675 }
3676 run_test 31a "open-unlink file =================================="
3677
3678 test_31b() {
3679         touch $DIR/f31 || error "touch $DIR/f31 failed"
3680         ln $DIR/f31 $DIR/f31b || error "ln failed"
3681         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3682         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3683 }
3684 run_test 31b "unlink file with multiple links while open ======="
3685
3686 test_31c() {
3687         touch $DIR/f31 || error "touch $DIR/f31 failed"
3688         ln $DIR/f31 $DIR/f31c || error "ln failed"
3689         multiop_bg_pause $DIR/f31 O_uc ||
3690                 error "multiop_bg_pause for $DIR/f31 failed"
3691         MULTIPID=$!
3692         $MULTIOP $DIR/f31c Ouc
3693         kill -USR1 $MULTIPID
3694         wait $MULTIPID
3695 }
3696 run_test 31c "open-unlink file with multiple links ============="
3697
3698 test_31d() {
3699         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3700         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3701 }
3702 run_test 31d "remove of open directory ========================="
3703
3704 test_31e() { # bug 2904
3705         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3706 }
3707 run_test 31e "remove of open non-empty directory ==============="
3708
3709 test_31f() { # bug 4554
3710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3711
3712         set -vx
3713         test_mkdir $DIR/d31f
3714         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3715         cp /etc/hosts $DIR/d31f
3716         ls -l $DIR/d31f
3717         $LFS getstripe $DIR/d31f/hosts
3718         multiop_bg_pause $DIR/d31f D_c || return 1
3719         MULTIPID=$!
3720
3721         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3722         test_mkdir $DIR/d31f
3723         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3724         cp /etc/hosts $DIR/d31f
3725         ls -l $DIR/d31f
3726         $LFS getstripe $DIR/d31f/hosts
3727         multiop_bg_pause $DIR/d31f D_c || return 1
3728         MULTIPID2=$!
3729
3730         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3731         wait $MULTIPID || error "first opendir $MULTIPID failed"
3732
3733         sleep 6
3734
3735         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3736         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3737         set +vx
3738 }
3739 run_test 31f "remove of open directory with open-unlink file ==="
3740
3741 test_31g() {
3742         echo "-- cross directory link --"
3743         test_mkdir -c1 $DIR/${tdir}ga
3744         test_mkdir -c1 $DIR/${tdir}gb
3745         touch $DIR/${tdir}ga/f
3746         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3747         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3748         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3749         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3750         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3751 }
3752 run_test 31g "cross directory link==============="
3753
3754 test_31h() {
3755         echo "-- cross directory link --"
3756         test_mkdir -c1 $DIR/${tdir}
3757         test_mkdir -c1 $DIR/${tdir}/dir
3758         touch $DIR/${tdir}/f
3759         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3760         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3761         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3762         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3763         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3764 }
3765 run_test 31h "cross directory link under child==============="
3766
3767 test_31i() {
3768         echo "-- cross directory link --"
3769         test_mkdir -c1 $DIR/$tdir
3770         test_mkdir -c1 $DIR/$tdir/dir
3771         touch $DIR/$tdir/dir/f
3772         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3773         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3774         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3775         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3776         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3777 }
3778 run_test 31i "cross directory link under parent==============="
3779
3780 test_31j() {
3781         test_mkdir -c1 -p $DIR/$tdir
3782         test_mkdir -c1 -p $DIR/$tdir/dir1
3783         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3784         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3785         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3786         return 0
3787 }
3788 run_test 31j "link for directory"
3789
3790 test_31k() {
3791         test_mkdir -c1 -p $DIR/$tdir
3792         touch $DIR/$tdir/s
3793         touch $DIR/$tdir/exist
3794         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3795         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3796         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3797         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3798         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3799         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3800         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3801         return 0
3802 }
3803 run_test 31k "link to file: the same, non-existing, dir"
3804
3805 test_31l() {
3806         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3807
3808         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3809         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3810                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3811
3812         touch $DIR/$tfile || error "create failed"
3813         mkdir $DIR/$tdir || error "mkdir failed"
3814         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3815 }
3816 run_test 31l "link to file: target dir has trailing slash"
3817
3818 test_31m() {
3819         mkdir $DIR/d31m
3820         touch $DIR/d31m/s
3821         mkdir $DIR/d31m2
3822         touch $DIR/d31m2/exist
3823         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3824         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3825         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3826         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3827         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3828         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3829         return 0
3830 }
3831 run_test 31m "link to file: the same, non-existing, dir"
3832
3833 test_31n() {
3834         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3835         nlink=$(stat --format=%h $DIR/$tfile)
3836         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3837         local fd=$(free_fd)
3838         local cmd="exec $fd<$DIR/$tfile"
3839         eval $cmd
3840         cmd="exec $fd<&-"
3841         trap "eval $cmd" EXIT
3842         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3843         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3844         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3845         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3846         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3847         eval $cmd
3848 }
3849 run_test 31n "check link count of unlinked file"
3850
3851 link_one() {
3852         local tempfile=$(mktemp $1_XXXXXX)
3853         link $tempfile $1 2> /dev/null &&
3854                 echo "$BASHPID: link $tempfile to $1 succeeded"
3855         unlink $tempfile
3856 }
3857
3858 test_31o() { # LU-2901
3859         test_mkdir $DIR/$tdir
3860         for LOOP in $(seq 100); do
3861                 rm -f $DIR/$tdir/$tfile*
3862                 for THREAD in $(seq 8); do
3863                         link_one $DIR/$tdir/$tfile.$LOOP &
3864                 done
3865                 wait
3866                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3867                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3868                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3869                         break || true
3870         done
3871 }
3872 run_test 31o "duplicate hard links with same filename"
3873
3874 test_31p() {
3875         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3876
3877         test_mkdir $DIR/$tdir
3878         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3879         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3880
3881         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3882                 error "open unlink test1 failed"
3883         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3884                 error "open unlink test2 failed"
3885
3886         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3887                 error "test1 still exists"
3888         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3889                 error "test2 still exists"
3890 }
3891 run_test 31p "remove of open striped directory"
3892
3893 test_31q() {
3894         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3895
3896         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3897         index=$($LFS getdirstripe -i $DIR/$tdir)
3898         [ $index -eq 3 ] || error "first stripe index $index != 3"
3899         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3900         [ $index -eq 1 ] || error "second stripe index $index != 1"
3901
3902         # when "-c <stripe_count>" is set, the number of MDTs specified after
3903         # "-i" should equal to the stripe count
3904         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3905 }
3906 run_test 31q "create striped directory on specific MDTs"
3907
3908 #LU-14949
3909 test_31r() {
3910         touch $DIR/$tfile.target
3911         touch $DIR/$tfile.source
3912
3913         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3914         $LCTL set_param fail_loc=0x1419 fail_val=3
3915         cat $DIR/$tfile.target &
3916         CATPID=$!
3917
3918         # Guarantee open is waiting before we get here
3919         sleep 1
3920         mv $DIR/$tfile.source $DIR/$tfile.target
3921
3922         wait $CATPID
3923         RC=$?
3924         if [[ $RC -ne 0 ]]; then
3925                 error "open with cat failed, rc=$RC"
3926         fi
3927 }
3928 run_test 31r "open-rename(replace) race"
3929
3930 cleanup_test32_mount() {
3931         local rc=0
3932         trap 0
3933         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3934         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3935         losetup -d $loopdev || true
3936         rm -rf $DIR/$tdir
3937         return $rc
3938 }
3939
3940 test_32a() {
3941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3942
3943         echo "== more mountpoints and symlinks ================="
3944         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3945         trap cleanup_test32_mount EXIT
3946         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3947         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3948                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3949         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3950                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3951         cleanup_test32_mount
3952 }
3953 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3954
3955 test_32b() {
3956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3957
3958         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3959         trap cleanup_test32_mount EXIT
3960         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3961         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3962                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3963         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3964                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3965         cleanup_test32_mount
3966 }
3967 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3968
3969 test_32c() {
3970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3971
3972         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3973         trap cleanup_test32_mount EXIT
3974         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3975         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3976                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3977         test_mkdir -p $DIR/$tdir/d2/test_dir
3978         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3979                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3980         cleanup_test32_mount
3981 }
3982 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3983
3984 test_32d() {
3985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3986
3987         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3988         trap cleanup_test32_mount EXIT
3989         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3990         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3991                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3992         test_mkdir -p $DIR/$tdir/d2/test_dir
3993         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3994                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3995         cleanup_test32_mount
3996 }
3997 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3998
3999 test_32e() {
4000         rm -fr $DIR/$tdir
4001         test_mkdir -p $DIR/$tdir/tmp
4002         local tmp_dir=$DIR/$tdir/tmp
4003         ln -s $DIR/$tdir $tmp_dir/symlink11
4004         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4005         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4006         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4007 }
4008 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4009
4010 test_32f() {
4011         rm -fr $DIR/$tdir
4012         test_mkdir -p $DIR/$tdir/tmp
4013         local tmp_dir=$DIR/$tdir/tmp
4014         ln -s $DIR/$tdir $tmp_dir/symlink11
4015         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4016         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4017         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4018 }
4019 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4020
4021 test_32g() {
4022         local tmp_dir=$DIR/$tdir/tmp
4023         test_mkdir -p $tmp_dir
4024         test_mkdir $DIR/${tdir}2
4025         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4026         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4027         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4028         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4029         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4030         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4031 }
4032 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4033
4034 test_32h() {
4035         rm -fr $DIR/$tdir $DIR/${tdir}2
4036         tmp_dir=$DIR/$tdir/tmp
4037         test_mkdir -p $tmp_dir
4038         test_mkdir $DIR/${tdir}2
4039         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4040         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4041         ls $tmp_dir/symlink12 || error "listing symlink12"
4042         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4043 }
4044 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4045
4046 test_32i() {
4047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4048
4049         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4050         trap cleanup_test32_mount EXIT
4051         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4052         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4053                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4054         touch $DIR/$tdir/test_file
4055         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4056                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4057         cleanup_test32_mount
4058 }
4059 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4060
4061 test_32j() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4065         trap cleanup_test32_mount EXIT
4066         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4067         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4068                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4069         touch $DIR/$tdir/test_file
4070         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4071                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4072         cleanup_test32_mount
4073 }
4074 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4075
4076 test_32k() {
4077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4078
4079         rm -fr $DIR/$tdir
4080         trap cleanup_test32_mount EXIT
4081         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4082         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4083                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4084         test_mkdir -p $DIR/$tdir/d2
4085         touch $DIR/$tdir/d2/test_file || error "touch failed"
4086         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4087                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4088         cleanup_test32_mount
4089 }
4090 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4091
4092 test_32l() {
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         rm -fr $DIR/$tdir
4096         trap cleanup_test32_mount EXIT
4097         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4098         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4099                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4100         test_mkdir -p $DIR/$tdir/d2
4101         touch $DIR/$tdir/d2/test_file || error "touch failed"
4102         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4103                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4104         cleanup_test32_mount
4105 }
4106 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4107
4108 test_32m() {
4109         rm -fr $DIR/d32m
4110         test_mkdir -p $DIR/d32m/tmp
4111         TMP_DIR=$DIR/d32m/tmp
4112         ln -s $DIR $TMP_DIR/symlink11
4113         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4114         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4115                 error "symlink11 not a link"
4116         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4117                 error "symlink01 not a link"
4118 }
4119 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4120
4121 test_32n() {
4122         rm -fr $DIR/d32n
4123         test_mkdir -p $DIR/d32n/tmp
4124         TMP_DIR=$DIR/d32n/tmp
4125         ln -s $DIR $TMP_DIR/symlink11
4126         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4127         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4128         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4129 }
4130 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4131
4132 test_32o() {
4133         touch $DIR/$tfile
4134         test_mkdir -p $DIR/d32o/tmp
4135         TMP_DIR=$DIR/d32o/tmp
4136         ln -s $DIR/$tfile $TMP_DIR/symlink12
4137         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4138         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4139                 error "symlink12 not a link"
4140         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4141         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4142                 error "$DIR/d32o/tmp/symlink12 not file type"
4143         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4144                 error "$DIR/d32o/symlink02 not file type"
4145 }
4146 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4147
4148 test_32p() {
4149         log 32p_1
4150         rm -fr $DIR/d32p
4151         log 32p_2
4152         rm -f $DIR/$tfile
4153         log 32p_3
4154         touch $DIR/$tfile
4155         log 32p_4
4156         test_mkdir -p $DIR/d32p/tmp
4157         log 32p_5
4158         TMP_DIR=$DIR/d32p/tmp
4159         log 32p_6
4160         ln -s $DIR/$tfile $TMP_DIR/symlink12
4161         log 32p_7
4162         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4163         log 32p_8
4164         cat $DIR/d32p/tmp/symlink12 ||
4165                 error "Can't open $DIR/d32p/tmp/symlink12"
4166         log 32p_9
4167         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4168         log 32p_10
4169 }
4170 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4171
4172 test_32q() {
4173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4174
4175         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4176         trap cleanup_test32_mount EXIT
4177         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4178         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4179         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4180                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4181         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4182         cleanup_test32_mount
4183 }
4184 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4185
4186 test_32r() {
4187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4188
4189         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4190         trap cleanup_test32_mount EXIT
4191         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4192         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4193         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4194                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4195         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4196         cleanup_test32_mount
4197 }
4198 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4199
4200 test_33aa() {
4201         rm -f $DIR/$tfile
4202         touch $DIR/$tfile
4203         chmod 444 $DIR/$tfile
4204         chown $RUNAS_ID $DIR/$tfile
4205         log 33_1
4206         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4207         log 33_2
4208 }
4209 run_test 33aa "write file with mode 444 (should return error)"
4210
4211 test_33a() {
4212         rm -fr $DIR/$tdir
4213         test_mkdir $DIR/$tdir
4214         chown $RUNAS_ID $DIR/$tdir
4215         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4216                 error "$RUNAS create $tdir/$tfile failed"
4217         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4218                 error "open RDWR" || true
4219 }
4220 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4221
4222 test_33b() {
4223         rm -fr $DIR/$tdir
4224         test_mkdir $DIR/$tdir
4225         chown $RUNAS_ID $DIR/$tdir
4226         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4227 }
4228 run_test 33b "test open file with malformed flags (No panic)"
4229
4230 test_33c() {
4231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4232         remote_ost_nodsh && skip "remote OST with nodsh"
4233
4234         local ostnum
4235         local ostname
4236         local write_bytes
4237         local all_zeros
4238
4239         all_zeros=true
4240         test_mkdir $DIR/$tdir
4241         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4242
4243         sync
4244         for ostnum in $(seq $OSTCOUNT); do
4245                 # test-framework's OST numbering is one-based, while Lustre's
4246                 # is zero-based
4247                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4248                 # check if at least some write_bytes stats are counted
4249                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4250                               obdfilter.$ostname.stats |
4251                               awk '/^write_bytes/ {print $7}' )
4252                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4253                 if (( ${write_bytes:-0} > 0 )); then
4254                         all_zeros=false
4255                         break
4256                 fi
4257         done
4258
4259         $all_zeros || return 0
4260
4261         # Write four bytes
4262         echo foo > $DIR/$tdir/bar
4263         # Really write them
4264         sync
4265
4266         # Total up write_bytes after writing.  We'd better find non-zeros.
4267         for ostnum in $(seq $OSTCOUNT); do
4268                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4269                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4270                               obdfilter/$ostname/stats |
4271                               awk '/^write_bytes/ {print $7}' )
4272                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4273                 if (( ${write_bytes:-0} > 0 )); then
4274                         all_zeros=false
4275                         break
4276                 fi
4277         done
4278
4279         if $all_zeros; then
4280                 for ostnum in $(seq $OSTCOUNT); do
4281                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4282                         echo "Check write_bytes is in obdfilter.*.stats:"
4283                         do_facet ost$ostnum lctl get_param -n \
4284                                 obdfilter.$ostname.stats
4285                 done
4286                 error "OST not keeping write_bytes stats (b=22312)"
4287         fi
4288 }
4289 run_test 33c "test write_bytes stats"
4290
4291 test_33d() {
4292         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4294
4295         local MDTIDX=1
4296         local remote_dir=$DIR/$tdir/remote_dir
4297
4298         test_mkdir $DIR/$tdir
4299         $LFS mkdir -i $MDTIDX $remote_dir ||
4300                 error "create remote directory failed"
4301
4302         touch $remote_dir/$tfile
4303         chmod 444 $remote_dir/$tfile
4304         chown $RUNAS_ID $remote_dir/$tfile
4305
4306         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4307
4308         chown $RUNAS_ID $remote_dir
4309         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4310                                         error "create" || true
4311         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4312                                     error "open RDWR" || true
4313         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4314 }
4315 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4316
4317 test_33e() {
4318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4319
4320         mkdir $DIR/$tdir
4321
4322         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4323         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4324         mkdir $DIR/$tdir/local_dir
4325
4326         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4327         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4328         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4329
4330         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4331                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4332
4333         rmdir $DIR/$tdir/* || error "rmdir failed"
4334
4335         umask 777
4336         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4337         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4338         mkdir $DIR/$tdir/local_dir
4339
4340         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4341         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4342         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4343
4344         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4345                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4346
4347         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4348
4349         umask 000
4350         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4351         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4352         mkdir $DIR/$tdir/local_dir
4353
4354         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4355         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4356         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4357
4358         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4359                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4360 }
4361 run_test 33e "mkdir and striped directory should have same mode"
4362
4363 cleanup_33f() {
4364         trap 0
4365         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4366 }
4367
4368 test_33f() {
4369         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4370         remote_mds_nodsh && skip "remote MDS with nodsh"
4371
4372         mkdir $DIR/$tdir
4373         chmod go+rwx $DIR/$tdir
4374         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4375         trap cleanup_33f EXIT
4376
4377         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4378                 error "cannot create striped directory"
4379
4380         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4381                 error "cannot create files in striped directory"
4382
4383         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4384                 error "cannot remove files in striped directory"
4385
4386         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4387                 error "cannot remove striped directory"
4388
4389         cleanup_33f
4390 }
4391 run_test 33f "nonroot user can create, access, and remove a striped directory"
4392
4393 test_33g() {
4394         mkdir -p $DIR/$tdir/dir2
4395
4396         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4397         echo $err
4398         [[ $err =~ "exists" ]] || error "Not exists error"
4399 }
4400 run_test 33g "nonroot user create already existing root created file"
4401
4402 sub_33h() {
4403         local hash_type=$1
4404         local count=250
4405
4406         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4407                 error "lfs mkdir -H $hash_type $tdir failed"
4408         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4409
4410         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4411         local index2
4412         local fname
4413
4414         for fname in $DIR/$tdir/$tfile.bak \
4415                      $DIR/$tdir/$tfile.SAV \
4416                      $DIR/$tdir/$tfile.orig \
4417                      $DIR/$tdir/$tfile~; do
4418                 touch $fname || error "touch $fname failed"
4419                 index2=$($LFS getstripe -m $fname)
4420                 (( $index == $index2 )) ||
4421                         error "$fname MDT index mismatch $index != $index2"
4422         done
4423
4424         local failed=0
4425         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4426         local pattern
4427
4428         for pattern in ${patterns[*]}; do
4429                 echo "pattern $pattern"
4430                 fname=$DIR/$tdir/$pattern
4431                 for (( i = 0; i < $count; i++ )); do
4432                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4433                                 error "mktemp $DIR/$tdir/$pattern failed"
4434                         index2=$($LFS getstripe -m $fname)
4435                         (( $index == $index2 )) && continue
4436
4437                         failed=$((failed + 1))
4438                         echo "$fname MDT index mismatch $index != $index2"
4439                 done
4440         done
4441
4442         echo "$failed/$count MDT index mismatches, expect ~2-4"
4443         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4444
4445         local same=0
4446         local expect
4447
4448         # verify that "crush" is still broken with all files on same MDT,
4449         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4450         [[ "$hash_type" == "crush" ]] && expect=$count ||
4451                 expect=$((count / MDSCOUNT))
4452
4453         # crush2 doesn't put all-numeric suffixes on the same MDT,
4454         # filename like $tfile.12345678 should *not* be considered temp
4455         for pattern in ${patterns[*]}; do
4456                 local base=${pattern%%X*}
4457                 local suff=${pattern#$base}
4458
4459                 echo "pattern $pattern"
4460                 for (( i = 0; i < $count; i++ )); do
4461                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4462                         touch $fname || error "touch $fname failed"
4463                         index2=$($LFS getstripe -m $fname)
4464                         (( $index != $index2 )) && continue
4465
4466                         same=$((same + 1))
4467                 done
4468         done
4469
4470         # the number of "bad" hashes is random, as it depends on the random
4471         # filenames generated by "mktemp".  Allow some margin in the results.
4472         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4473         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4474            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4475                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4476         same=0
4477
4478         # crush2 doesn't put suffixes with special characters on the same MDT
4479         # filename like $tfile.txt.1234 should *not* be considered temp
4480         for pattern in ${patterns[*]}; do
4481                 local base=${pattern%%X*}
4482                 local suff=${pattern#$base}
4483
4484                 pattern=$base...${suff/XXX}
4485                 echo "pattern=$pattern"
4486                 for (( i = 0; i < $count; i++ )); do
4487                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4488                                 error "touch $fname failed"
4489                         index2=$($LFS getstripe -m $fname)
4490                         (( $index != $index2 )) && continue
4491
4492                         same=$((same + 1))
4493                 done
4494         done
4495
4496         # the number of "bad" hashes is random, as it depends on the random
4497         # filenames generated by "mktemp".  Allow some margin in the results.
4498         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4499         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4500            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4501                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4502 }
4503
4504 test_33h() {
4505         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4506         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4507                 skip "Need MDS version at least 2.13.50"
4508
4509         sub_33h crush
4510 }
4511 run_test 33h "temp file is located on the same MDT as target (crush)"
4512
4513 test_33hh() {
4514         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4515         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4516         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4517                 skip "Need MDS version at least 2.15.0 for crush2"
4518
4519         sub_33h crush2
4520 }
4521 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4522
4523 test_33i()
4524 {
4525         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4526
4527         local FNAME=$(str_repeat 'f' 250)
4528
4529         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4530         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4531
4532         local count
4533         local total
4534
4535         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4536
4537         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4538
4539         lctl --device %$MDC deactivate
4540         stack_trap "lctl --device %$MDC activate"
4541         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4542         total=$(\ls -l $DIR/$tdir | wc -l)
4543         # "ls -l" will list total in the first line
4544         total=$((total - 1))
4545         (( total + count == 1000 )) ||
4546                 error "ls list $total files, $count files on MDT1"
4547 }
4548 run_test 33i "striped directory can be accessed when one MDT is down"
4549
4550 test_33j() {
4551         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4552
4553         mkdir -p $DIR/$tdir/
4554
4555         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4556                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4557
4558         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4559                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4560
4561         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4562                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4563
4564         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4565                 error "-D was not specified, but still failed"
4566 }
4567 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4568
4569 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4570 test_34a() {
4571         rm -f $DIR/f34
4572         $MCREATE $DIR/f34 || error "mcreate failed"
4573         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4574                 error "getstripe failed"
4575         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4576         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4577                 error "getstripe failed"
4578         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4579                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4580 }
4581 run_test 34a "truncate file that has not been opened ==========="
4582
4583 test_34b() {
4584         [ ! -f $DIR/f34 ] && test_34a
4585         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4586                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4587         $OPENFILE -f O_RDONLY $DIR/f34
4588         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4589                 error "getstripe failed"
4590         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4591                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4592 }
4593 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4594
4595 test_34c() {
4596         [ ! -f $DIR/f34 ] && test_34a
4597         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4598                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4599         $OPENFILE -f O_RDWR $DIR/f34
4600         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4601                 error "$LFS getstripe failed"
4602         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4603                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4604 }
4605 run_test 34c "O_RDWR opening file-with-size works =============="
4606
4607 test_34d() {
4608         [ ! -f $DIR/f34 ] && test_34a
4609         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4610                 error "dd failed"
4611         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4612                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4613         rm $DIR/f34
4614 }
4615 run_test 34d "write to sparse file ============================="
4616
4617 test_34e() {
4618         rm -f $DIR/f34e
4619         $MCREATE $DIR/f34e || error "mcreate failed"
4620         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4621         $CHECKSTAT -s 1000 $DIR/f34e ||
4622                 error "Size of $DIR/f34e not equal to 1000 bytes"
4623         $OPENFILE -f O_RDWR $DIR/f34e
4624         $CHECKSTAT -s 1000 $DIR/f34e ||
4625                 error "Size of $DIR/f34e not equal to 1000 bytes"
4626 }
4627 run_test 34e "create objects, some with size and some without =="
4628
4629 test_34f() { # bug 6242, 6243
4630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4631
4632         SIZE34F=48000
4633         rm -f $DIR/f34f
4634         $MCREATE $DIR/f34f || error "mcreate failed"
4635         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4636         dd if=$DIR/f34f of=$TMP/f34f
4637         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4638         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4639         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4640         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4641         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4642 }
4643 run_test 34f "read from a file with no objects until EOF ======="
4644
4645 test_34g() {
4646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4647
4648         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4649                 error "dd failed"
4650         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4651         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4652                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4653         cancel_lru_locks osc
4654         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4655                 error "wrong size after lock cancel"
4656
4657         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4658         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4659                 error "expanding truncate failed"
4660         cancel_lru_locks osc
4661         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4662                 error "wrong expanded size after lock cancel"
4663 }
4664 run_test 34g "truncate long file ==============================="
4665
4666 test_34h() {
4667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4668
4669         local gid=10
4670         local sz=1000
4671
4672         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4673         sync # Flush the cache so that multiop below does not block on cache
4674              # flush when getting the group lock
4675         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4676         MULTIPID=$!
4677
4678         # Since just timed wait is not good enough, let's do a sync write
4679         # that way we are sure enough time for a roundtrip + processing
4680         # passed + 2 seconds of extra margin.
4681         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4682         rm $DIR/${tfile}-1
4683         sleep 2
4684
4685         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4686                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4687                 kill -9 $MULTIPID
4688         fi
4689         wait $MULTIPID
4690         local nsz=`stat -c %s $DIR/$tfile`
4691         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4692 }
4693 run_test 34h "ftruncate file under grouplock should not block"
4694
4695 test_35a() {
4696         cp /bin/sh $DIR/f35a
4697         chmod 444 $DIR/f35a
4698         chown $RUNAS_ID $DIR/f35a
4699         $RUNAS $DIR/f35a && error || true
4700         rm $DIR/f35a
4701 }
4702 run_test 35a "exec file with mode 444 (should return and not leak)"
4703
4704 test_36a() {
4705         rm -f $DIR/f36
4706         utime $DIR/f36 || error "utime failed for MDS"
4707 }
4708 run_test 36a "MDS utime check (mknod, utime)"
4709
4710 test_36b() {
4711         echo "" > $DIR/f36
4712         utime $DIR/f36 || error "utime failed for OST"
4713 }
4714 run_test 36b "OST utime check (open, utime)"
4715
4716 test_36c() {
4717         rm -f $DIR/d36/f36
4718         test_mkdir $DIR/d36
4719         chown $RUNAS_ID $DIR/d36
4720         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4721 }
4722 run_test 36c "non-root MDS utime check (mknod, utime)"
4723
4724 test_36d() {
4725         [ ! -d $DIR/d36 ] && test_36c
4726         echo "" > $DIR/d36/f36
4727         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4728 }
4729 run_test 36d "non-root OST utime check (open, utime)"
4730
4731 test_36e() {
4732         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4733
4734         test_mkdir $DIR/$tdir
4735         touch $DIR/$tdir/$tfile
4736         $RUNAS utime $DIR/$tdir/$tfile &&
4737                 error "utime worked, expected failure" || true
4738 }
4739 run_test 36e "utime on non-owned file (should return error)"
4740
4741 subr_36fh() {
4742         local fl="$1"
4743         local LANG_SAVE=$LANG
4744         local LC_LANG_SAVE=$LC_LANG
4745         export LANG=C LC_LANG=C # for date language
4746
4747         DATESTR="Dec 20  2000"
4748         test_mkdir $DIR/$tdir
4749         lctl set_param fail_loc=$fl
4750         date; date +%s
4751         cp /etc/hosts $DIR/$tdir/$tfile
4752         sync & # write RPC generated with "current" inode timestamp, but delayed
4753         sleep 1
4754         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4755         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4756         cancel_lru_locks $OSC
4757         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4758         date; date +%s
4759         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4760                 echo "BEFORE: $LS_BEFORE" && \
4761                 echo "AFTER : $LS_AFTER" && \
4762                 echo "WANT  : $DATESTR" && \
4763                 error "$DIR/$tdir/$tfile timestamps changed" || true
4764
4765         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4766 }
4767
4768 test_36f() {
4769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4770
4771         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4772         subr_36fh "0x80000214"
4773 }
4774 run_test 36f "utime on file racing with OST BRW write =========="
4775
4776 test_36g() {
4777         remote_ost_nodsh && skip "remote OST with nodsh"
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4780                 skip "Need MDS version at least 2.12.51"
4781
4782         local fmd_max_age
4783         local fmd
4784         local facet="ost1"
4785         local tgt="obdfilter"
4786
4787         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4788
4789         test_mkdir $DIR/$tdir
4790         fmd_max_age=$(do_facet $facet \
4791                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4792                 head -n 1")
4793
4794         echo "FMD max age: ${fmd_max_age}s"
4795         touch $DIR/$tdir/$tfile
4796         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4797                 gawk '{cnt=cnt+$1}  END{print cnt}')
4798         echo "FMD before: $fmd"
4799         [[ $fmd == 0 ]] &&
4800                 error "FMD wasn't create by touch"
4801         sleep $((fmd_max_age + 12))
4802         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4803                 gawk '{cnt=cnt+$1}  END{print cnt}')
4804         echo "FMD after: $fmd"
4805         [[ $fmd == 0 ]] ||
4806                 error "FMD wasn't expired by ping"
4807 }
4808 run_test 36g "FMD cache expiry ====================="
4809
4810 test_36h() {
4811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4812
4813         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4814         subr_36fh "0x80000227"
4815 }
4816 run_test 36h "utime on file racing with OST BRW write =========="
4817
4818 test_36i() {
4819         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4820
4821         test_mkdir $DIR/$tdir
4822         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4823
4824         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4825         local new_mtime=$((mtime + 200))
4826
4827         #change Modify time of striped dir
4828         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4829                         error "change mtime failed"
4830
4831         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4832
4833         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4834 }
4835 run_test 36i "change mtime on striped directory"
4836
4837 # test_37 - duplicate with tests 32q 32r
4838
4839 test_38() {
4840         local file=$DIR/$tfile
4841         touch $file
4842         openfile -f O_DIRECTORY $file
4843         local RC=$?
4844         local ENOTDIR=20
4845         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4846         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4847 }
4848 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4849
4850 test_39a() { # was test_39
4851         touch $DIR/$tfile
4852         touch $DIR/${tfile}2
4853 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4854 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4855 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4856         sleep 2
4857         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4858         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4859                 echo "mtime"
4860                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4861                 echo "atime"
4862                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4863                 echo "ctime"
4864                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4865                 error "O_TRUNC didn't change timestamps"
4866         fi
4867 }
4868 run_test 39a "mtime changed on create"
4869
4870 test_39b() {
4871         test_mkdir -c1 $DIR/$tdir
4872         cp -p /etc/passwd $DIR/$tdir/fopen
4873         cp -p /etc/passwd $DIR/$tdir/flink
4874         cp -p /etc/passwd $DIR/$tdir/funlink
4875         cp -p /etc/passwd $DIR/$tdir/frename
4876         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4877
4878         sleep 1
4879         echo "aaaaaa" >> $DIR/$tdir/fopen
4880         echo "aaaaaa" >> $DIR/$tdir/flink
4881         echo "aaaaaa" >> $DIR/$tdir/funlink
4882         echo "aaaaaa" >> $DIR/$tdir/frename
4883
4884         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4885         local link_new=`stat -c %Y $DIR/$tdir/flink`
4886         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4887         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4888
4889         cat $DIR/$tdir/fopen > /dev/null
4890         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4891         rm -f $DIR/$tdir/funlink2
4892         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4893
4894         for (( i=0; i < 2; i++ )) ; do
4895                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4896                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4897                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4898                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4899
4900                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4901                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4902                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4903                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4904
4905                 cancel_lru_locks $OSC
4906                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4907         done
4908 }
4909 run_test 39b "mtime change on open, link, unlink, rename  ======"
4910
4911 # this should be set to past
4912 TEST_39_MTIME=`date -d "1 year ago" +%s`
4913
4914 # bug 11063
4915 test_39c() {
4916         touch $DIR1/$tfile
4917         sleep 2
4918         local mtime0=`stat -c %Y $DIR1/$tfile`
4919
4920         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4921         local mtime1=`stat -c %Y $DIR1/$tfile`
4922         [ "$mtime1" = $TEST_39_MTIME ] || \
4923                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4924
4925         local d1=`date +%s`
4926         echo hello >> $DIR1/$tfile
4927         local d2=`date +%s`
4928         local mtime2=`stat -c %Y $DIR1/$tfile`
4929         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4930                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4931
4932         mv $DIR1/$tfile $DIR1/$tfile-1
4933
4934         for (( i=0; i < 2; i++ )) ; do
4935                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4936                 [ "$mtime2" = "$mtime3" ] || \
4937                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4938
4939                 cancel_lru_locks $OSC
4940                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4941         done
4942 }
4943 run_test 39c "mtime change on rename ==========================="
4944
4945 # bug 21114
4946 test_39d() {
4947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4948
4949         touch $DIR1/$tfile
4950         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4951
4952         for (( i=0; i < 2; i++ )) ; do
4953                 local mtime=`stat -c %Y $DIR1/$tfile`
4954                 [ $mtime = $TEST_39_MTIME ] || \
4955                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4956
4957                 cancel_lru_locks $OSC
4958                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4959         done
4960 }
4961 run_test 39d "create, utime, stat =============================="
4962
4963 # bug 21114
4964 test_39e() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966
4967         touch $DIR1/$tfile
4968         local mtime1=`stat -c %Y $DIR1/$tfile`
4969
4970         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4971
4972         for (( i=0; i < 2; i++ )) ; do
4973                 local mtime2=`stat -c %Y $DIR1/$tfile`
4974                 [ $mtime2 = $TEST_39_MTIME ] || \
4975                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4976
4977                 cancel_lru_locks $OSC
4978                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4979         done
4980 }
4981 run_test 39e "create, stat, utime, stat ========================"
4982
4983 # bug 21114
4984 test_39f() {
4985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4986
4987         touch $DIR1/$tfile
4988         mtime1=`stat -c %Y $DIR1/$tfile`
4989
4990         sleep 2
4991         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4992
4993         for (( i=0; i < 2; i++ )) ; do
4994                 local mtime2=`stat -c %Y $DIR1/$tfile`
4995                 [ $mtime2 = $TEST_39_MTIME ] || \
4996                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4997
4998                 cancel_lru_locks $OSC
4999                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5000         done
5001 }
5002 run_test 39f "create, stat, sleep, utime, stat ================="
5003
5004 # bug 11063
5005 test_39g() {
5006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5007
5008         echo hello >> $DIR1/$tfile
5009         local mtime1=`stat -c %Y $DIR1/$tfile`
5010
5011         sleep 2
5012         chmod o+r $DIR1/$tfile
5013
5014         for (( i=0; i < 2; i++ )) ; do
5015                 local mtime2=`stat -c %Y $DIR1/$tfile`
5016                 [ "$mtime1" = "$mtime2" ] || \
5017                         error "lost mtime: $mtime2, should be $mtime1"
5018
5019                 cancel_lru_locks $OSC
5020                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5021         done
5022 }
5023 run_test 39g "write, chmod, stat ==============================="
5024
5025 # bug 11063
5026 test_39h() {
5027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5028
5029         touch $DIR1/$tfile
5030         sleep 1
5031
5032         local d1=`date`
5033         echo hello >> $DIR1/$tfile
5034         local mtime1=`stat -c %Y $DIR1/$tfile`
5035
5036         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5037         local d2=`date`
5038         if [ "$d1" != "$d2" ]; then
5039                 echo "write and touch not within one second"
5040         else
5041                 for (( i=0; i < 2; i++ )) ; do
5042                         local mtime2=`stat -c %Y $DIR1/$tfile`
5043                         [ "$mtime2" = $TEST_39_MTIME ] || \
5044                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5045
5046                         cancel_lru_locks $OSC
5047                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5048                 done
5049         fi
5050 }
5051 run_test 39h "write, utime within one second, stat ============="
5052
5053 test_39i() {
5054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5055
5056         touch $DIR1/$tfile
5057         sleep 1
5058
5059         echo hello >> $DIR1/$tfile
5060         local mtime1=`stat -c %Y $DIR1/$tfile`
5061
5062         mv $DIR1/$tfile $DIR1/$tfile-1
5063
5064         for (( i=0; i < 2; i++ )) ; do
5065                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5066
5067                 [ "$mtime1" = "$mtime2" ] || \
5068                         error "lost mtime: $mtime2, should be $mtime1"
5069
5070                 cancel_lru_locks $OSC
5071                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5072         done
5073 }
5074 run_test 39i "write, rename, stat =============================="
5075
5076 test_39j() {
5077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5078
5079         start_full_debug_logging
5080         touch $DIR1/$tfile
5081         sleep 1
5082
5083         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5084         lctl set_param fail_loc=0x80000412
5085         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5086                 error "multiop failed"
5087         local multipid=$!
5088         local mtime1=`stat -c %Y $DIR1/$tfile`
5089
5090         mv $DIR1/$tfile $DIR1/$tfile-1
5091
5092         kill -USR1 $multipid
5093         wait $multipid || error "multiop close failed"
5094
5095         for (( i=0; i < 2; i++ )) ; do
5096                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5097                 [ "$mtime1" = "$mtime2" ] ||
5098                         error "mtime is lost on close: $mtime2, " \
5099                               "should be $mtime1"
5100
5101                 cancel_lru_locks
5102                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5103         done
5104         lctl set_param fail_loc=0
5105         stop_full_debug_logging
5106 }
5107 run_test 39j "write, rename, close, stat ======================="
5108
5109 test_39k() {
5110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5111
5112         touch $DIR1/$tfile
5113         sleep 1
5114
5115         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5116         local multipid=$!
5117         local mtime1=`stat -c %Y $DIR1/$tfile`
5118
5119         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5120
5121         kill -USR1 $multipid
5122         wait $multipid || error "multiop close failed"
5123
5124         for (( i=0; i < 2; i++ )) ; do
5125                 local mtime2=`stat -c %Y $DIR1/$tfile`
5126
5127                 [ "$mtime2" = $TEST_39_MTIME ] || \
5128                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5129
5130                 cancel_lru_locks
5131                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5132         done
5133 }
5134 run_test 39k "write, utime, close, stat ========================"
5135
5136 # this should be set to future
5137 TEST_39_ATIME=`date -d "1 year" +%s`
5138
5139 test_39l() {
5140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5141         remote_mds_nodsh && skip "remote MDS with nodsh"
5142
5143         local atime_diff=$(do_facet $SINGLEMDS \
5144                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5145         rm -rf $DIR/$tdir
5146         mkdir_on_mdt0 $DIR/$tdir
5147
5148         # test setting directory atime to future
5149         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5150         local atime=$(stat -c %X $DIR/$tdir)
5151         [ "$atime" = $TEST_39_ATIME ] ||
5152                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5153
5154         # test setting directory atime from future to now
5155         local now=$(date +%s)
5156         touch -a -d @$now $DIR/$tdir
5157
5158         atime=$(stat -c %X $DIR/$tdir)
5159         [ "$atime" -eq "$now"  ] ||
5160                 error "atime is not updated from future: $atime, $now"
5161
5162         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5163         sleep 3
5164
5165         # test setting directory atime when now > dir atime + atime_diff
5166         local d1=$(date +%s)
5167         ls $DIR/$tdir
5168         local d2=$(date +%s)
5169         cancel_lru_locks mdc
5170         atime=$(stat -c %X $DIR/$tdir)
5171         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5172                 error "atime is not updated  : $atime, should be $d2"
5173
5174         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5175         sleep 3
5176
5177         # test not setting directory atime when now < dir atime + atime_diff
5178         ls $DIR/$tdir
5179         cancel_lru_locks mdc
5180         atime=$(stat -c %X $DIR/$tdir)
5181         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5182                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5183
5184         do_facet $SINGLEMDS \
5185                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5186 }
5187 run_test 39l "directory atime update ==========================="
5188
5189 test_39m() {
5190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5191
5192         touch $DIR1/$tfile
5193         sleep 2
5194         local far_past_mtime=$(date -d "May 29 1953" +%s)
5195         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5196
5197         touch -m -d @$far_past_mtime $DIR1/$tfile
5198         touch -a -d @$far_past_atime $DIR1/$tfile
5199
5200         for (( i=0; i < 2; i++ )) ; do
5201                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5202                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5203                         error "atime or mtime set incorrectly"
5204
5205                 cancel_lru_locks $OSC
5206                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5207         done
5208 }
5209 run_test 39m "test atime and mtime before 1970"
5210
5211 test_39n() { # LU-3832
5212         remote_mds_nodsh && skip "remote MDS with nodsh"
5213
5214         local atime_diff=$(do_facet $SINGLEMDS \
5215                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5216         local atime0
5217         local atime1
5218         local atime2
5219
5220         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5221
5222         rm -rf $DIR/$tfile
5223         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5224         atime0=$(stat -c %X $DIR/$tfile)
5225
5226         sleep 5
5227         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5228         atime1=$(stat -c %X $DIR/$tfile)
5229
5230         sleep 5
5231         cancel_lru_locks mdc
5232         cancel_lru_locks osc
5233         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5234         atime2=$(stat -c %X $DIR/$tfile)
5235
5236         do_facet $SINGLEMDS \
5237                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5238
5239         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5240         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5241 }
5242 run_test 39n "check that O_NOATIME is honored"
5243
5244 test_39o() {
5245         TESTDIR=$DIR/$tdir/$tfile
5246         [ -e $TESTDIR ] && rm -rf $TESTDIR
5247         mkdir -p $TESTDIR
5248         cd $TESTDIR
5249         links1=2
5250         ls
5251         mkdir a b
5252         ls
5253         links2=$(stat -c %h .)
5254         [ $(($links1 + 2)) != $links2 ] &&
5255                 error "wrong links count $(($links1 + 2)) != $links2"
5256         rmdir b
5257         links3=$(stat -c %h .)
5258         [ $(($links1 + 1)) != $links3 ] &&
5259                 error "wrong links count $links1 != $links3"
5260         return 0
5261 }
5262 run_test 39o "directory cached attributes updated after create"
5263
5264 test_39p() {
5265         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5266
5267         local MDTIDX=1
5268         TESTDIR=$DIR/$tdir/$tdir
5269         [ -e $TESTDIR ] && rm -rf $TESTDIR
5270         test_mkdir -p $TESTDIR
5271         cd $TESTDIR
5272         links1=2
5273         ls
5274         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5275         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5276         ls
5277         links2=$(stat -c %h .)
5278         [ $(($links1 + 2)) != $links2 ] &&
5279                 error "wrong links count $(($links1 + 2)) != $links2"
5280         rmdir remote_dir2
5281         links3=$(stat -c %h .)
5282         [ $(($links1 + 1)) != $links3 ] &&
5283                 error "wrong links count $links1 != $links3"
5284         return 0
5285 }
5286 run_test 39p "remote directory cached attributes updated after create ========"
5287
5288 test_39r() {
5289         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5290                 skip "no atime update on old OST"
5291         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5292                 skip_env "ldiskfs only test"
5293         fi
5294
5295         local saved_adiff
5296         local ahost=$(facet_active_host ost1)
5297         saved_adiff=$(do_facet ost1 \
5298                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5299         stack_trap "do_facet ost1 \
5300                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5301
5302         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5303
5304         $LFS setstripe -i 0 $DIR/$tfile
5305         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5306                 error "can't write initial file"
5307         cancel_lru_locks osc
5308
5309         # exceed atime_diff and access file
5310         sleep 10
5311         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5312                 error "can't udpate atime"
5313
5314         # atime_cli value is in decimal
5315         local atime_cli=$(stat -c %X $DIR/$tfile)
5316         echo "client atime: $atime_cli"
5317
5318         local ostdev=$(ostdevname 1)
5319         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5320         local seq=${fid[3]#0x}
5321         local oid=${fid[1]}
5322         local oid_hex
5323
5324         if [ $seq == 0 ]; then
5325                 oid_hex=${fid[1]}
5326         else
5327                 oid_hex=${fid[2]#0x}
5328         fi
5329         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5330         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5331
5332         # allow atime update to be written to device
5333         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5334         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5335
5336         # Give enough time for server to get updated. Until then
5337         # the value read is defaulted to "0x00000000:00000000"
5338         # Wait until atime read via debugfs is not equal to zero.
5339         # Max limit to wait is 30 seconds.
5340         wait_update_cond $ahost                                         \
5341                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5342                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5343         # atime_ost value is in hex
5344         local atime_ost=$(do_facet ost1 "$cmd" |&
5345                           awk -F'[: ]' '/atime:/ { print $4 }')
5346         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5347         # convert Hex to decimal before comparing
5348         local atime_ost_dec=$((atime_ost))
5349
5350         # The test pass criteria is that the client time and server should
5351         # be same (2s gap accepted). This gap could arise due to VFS updating
5352         # the atime after the read(dd), stat and the updated time from the
5353         # inode
5354         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5355                 error "atime on client $atime_cli != ost $atime_ost_dec"
5356 }
5357 run_test 39r "lazy atime update on OST"
5358
5359 test_39q() { # LU-8041
5360         local testdir=$DIR/$tdir
5361         mkdir -p $testdir
5362         multiop_bg_pause $testdir D_c || error "multiop failed"
5363         local multipid=$!
5364         cancel_lru_locks mdc
5365         kill -USR1 $multipid
5366         local atime=$(stat -c %X $testdir)
5367         [ "$atime" -ne 0 ] || error "atime is zero"
5368 }
5369 run_test 39q "close won't zero out atime"
5370
5371 test_39s() {
5372         local atime0
5373         local atime1
5374         local atime2
5375         local atime3
5376         local atime4
5377
5378         umount_client $MOUNT
5379         mount_client $MOUNT relatime
5380
5381         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5382         atime0=$(stat -c %X $DIR/$tfile)
5383
5384         # First read updates atime
5385         sleep 1
5386         cat $DIR/$tfile >/dev/null
5387         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5388
5389         # Next reads do not update atime
5390         sleep 1
5391         cat $DIR/$tfile >/dev/null
5392         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5393
5394         # If mtime is greater than atime, atime is updated
5395         sleep 1
5396         touch -m $DIR/$tfile # (mtime = now)
5397         sleep 1
5398         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5399         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5400
5401         # Next reads do not update atime
5402         sleep 1
5403         cat $DIR/$tfile >/dev/null
5404         atime4=$(stat -c %X $DIR/$tfile)
5405
5406         # Remount the client to clear 'relatime' option
5407         remount_client $MOUNT
5408
5409         (( atime0 < atime1 )) ||
5410                 error "atime $atime0 should be smaller than $atime1"
5411         (( atime1 == atime2 )) ||
5412                 error "atime $atime1 was updated to $atime2"
5413         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5414         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5415 }
5416 run_test 39s "relatime is supported"
5417
5418 test_40() {
5419         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5420         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5421                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5422         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5423                 error "$tfile is not 4096 bytes in size"
5424 }
5425 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5426
5427 test_41() {
5428         # bug 1553
5429         small_write $DIR/f41 18
5430 }
5431 run_test 41 "test small file write + fstat ====================="
5432
5433 count_ost_writes() {
5434         lctl get_param -n ${OSC}.*.stats |
5435                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5436                         END { printf("%0.0f", writes) }'
5437 }
5438
5439 # decent default
5440 WRITEBACK_SAVE=500
5441 DIRTY_RATIO_SAVE=40
5442 MAX_DIRTY_RATIO=50
5443 BG_DIRTY_RATIO_SAVE=10
5444 MAX_BG_DIRTY_RATIO=25
5445
5446 start_writeback() {
5447         trap 0
5448         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5449         # dirty_ratio, dirty_background_ratio
5450         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5451                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5452                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5453                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5454         else
5455                 # if file not here, we are a 2.4 kernel
5456                 kill -CONT `pidof kupdated`
5457         fi
5458 }
5459
5460 stop_writeback() {
5461         # setup the trap first, so someone cannot exit the test at the
5462         # exact wrong time and mess up a machine
5463         trap start_writeback EXIT
5464         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5465         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5466                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5467                 sysctl -w vm.dirty_writeback_centisecs=0
5468                 sysctl -w vm.dirty_writeback_centisecs=0
5469                 # save and increase /proc/sys/vm/dirty_ratio
5470                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5471                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5472                 # save and increase /proc/sys/vm/dirty_background_ratio
5473                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5474                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5475         else
5476                 # if file not here, we are a 2.4 kernel
5477                 kill -STOP `pidof kupdated`
5478         fi
5479 }
5480
5481 # ensure that all stripes have some grant before we test client-side cache
5482 setup_test42() {
5483         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5484                 dd if=/dev/zero of=$i bs=4k count=1
5485                 rm $i
5486         done
5487 }
5488
5489 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5490 # file truncation, and file removal.
5491 test_42a() {
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493
5494         setup_test42
5495         cancel_lru_locks $OSC
5496         stop_writeback
5497         sync; sleep 1; sync # just to be safe
5498         BEFOREWRITES=`count_ost_writes`
5499         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5500         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5501         AFTERWRITES=`count_ost_writes`
5502         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5503                 error "$BEFOREWRITES < $AFTERWRITES"
5504         start_writeback
5505 }
5506 run_test 42a "ensure that we don't flush on close"
5507
5508 test_42b() {
5509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5510
5511         setup_test42
5512         cancel_lru_locks $OSC
5513         stop_writeback
5514         sync
5515         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5516         BEFOREWRITES=$(count_ost_writes)
5517         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5518         AFTERWRITES=$(count_ost_writes)
5519         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5520                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5521         fi
5522         BEFOREWRITES=$(count_ost_writes)
5523         sync || error "sync: $?"
5524         AFTERWRITES=$(count_ost_writes)
5525         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5526                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5527         fi
5528         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5529         start_writeback
5530         return 0
5531 }
5532 run_test 42b "test destroy of file with cached dirty data ======"
5533
5534 # if these tests just want to test the effect of truncation,
5535 # they have to be very careful.  consider:
5536 # - the first open gets a {0,EOF}PR lock
5537 # - the first write conflicts and gets a {0, count-1}PW
5538 # - the rest of the writes are under {count,EOF}PW
5539 # - the open for truncate tries to match a {0,EOF}PR
5540 #   for the filesize and cancels the PWs.
5541 # any number of fixes (don't get {0,EOF} on open, match
5542 # composite locks, do smarter file size management) fix
5543 # this, but for now we want these tests to verify that
5544 # the cancellation with truncate intent works, so we
5545 # start the file with a full-file pw lock to match against
5546 # until the truncate.
5547 trunc_test() {
5548         test=$1
5549         file=$DIR/$test
5550         offset=$2
5551         cancel_lru_locks $OSC
5552         stop_writeback
5553         # prime the file with 0,EOF PW to match
5554         touch $file
5555         $TRUNCATE $file 0
5556         sync; sync
5557         # now the real test..
5558         dd if=/dev/zero of=$file bs=1024 count=100
5559         BEFOREWRITES=`count_ost_writes`
5560         $TRUNCATE $file $offset
5561         cancel_lru_locks $OSC
5562         AFTERWRITES=`count_ost_writes`
5563         start_writeback
5564 }
5565
5566 test_42c() {
5567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5568
5569         trunc_test 42c 1024
5570         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5571                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5572         rm $file
5573 }
5574 run_test 42c "test partial truncate of file with cached dirty data"
5575
5576 test_42d() {
5577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5578
5579         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5580         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5581         $LCTL set_param debug=+cache
5582
5583         trunc_test 42d 0
5584         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5585                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5586         rm $file
5587 }
5588 run_test 42d "test complete truncate of file with cached dirty data"
5589
5590 test_42e() { # bug22074
5591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5592
5593         local TDIR=$DIR/${tdir}e
5594         local pages=16 # hardcoded 16 pages, don't change it.
5595         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5596         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5597         local max_dirty_mb
5598         local warmup_files
5599
5600         test_mkdir $DIR/${tdir}e
5601         $LFS setstripe -c 1 $TDIR
5602         createmany -o $TDIR/f $files
5603
5604         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5605
5606         # we assume that with $OSTCOUNT files, at least one of them will
5607         # be allocated on OST0.
5608         warmup_files=$((OSTCOUNT * max_dirty_mb))
5609         createmany -o $TDIR/w $warmup_files
5610
5611         # write a large amount of data into one file and sync, to get good
5612         # avail_grant number from OST.
5613         for ((i=0; i<$warmup_files; i++)); do
5614                 idx=$($LFS getstripe -i $TDIR/w$i)
5615                 [ $idx -ne 0 ] && continue
5616                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5617                 break
5618         done
5619         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5620         sync
5621         $LCTL get_param $proc_osc0/cur_dirty_bytes
5622         $LCTL get_param $proc_osc0/cur_grant_bytes
5623
5624         # create as much dirty pages as we can while not to trigger the actual
5625         # RPCs directly. but depends on the env, VFS may trigger flush during this
5626         # period, hopefully we are good.
5627         for ((i=0; i<$warmup_files; i++)); do
5628                 idx=$($LFS getstripe -i $TDIR/w$i)
5629                 [ $idx -ne 0 ] && continue
5630                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5631         done
5632         $LCTL get_param $proc_osc0/cur_dirty_bytes
5633         $LCTL get_param $proc_osc0/cur_grant_bytes
5634
5635         # perform the real test
5636         $LCTL set_param $proc_osc0/rpc_stats 0
5637         for ((;i<$files; i++)); do
5638                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5639                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5640         done
5641         sync
5642         $LCTL get_param $proc_osc0/rpc_stats
5643
5644         local percent=0
5645         local have_ppr=false
5646         $LCTL get_param $proc_osc0/rpc_stats |
5647                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5648                         # skip lines until we are at the RPC histogram data
5649                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5650                         $have_ppr || continue
5651
5652                         # we only want the percent stat for < 16 pages
5653                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5654
5655                         percent=$((percent + WPCT))
5656                         if [[ $percent -gt 15 ]]; then
5657                                 error "less than 16-pages write RPCs" \
5658                                       "$percent% > 15%"
5659                                 break
5660                         fi
5661                 done
5662         rm -rf $TDIR
5663 }
5664 run_test 42e "verify sub-RPC writes are not done synchronously"
5665
5666 test_43A() { # was test_43
5667         test_mkdir $DIR/$tdir
5668         cp -p /bin/ls $DIR/$tdir/$tfile
5669         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5670         pid=$!
5671         # give multiop a chance to open
5672         sleep 1
5673
5674         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5675         kill -USR1 $pid
5676         # Wait for multiop to exit
5677         wait $pid
5678 }
5679 run_test 43A "execution of file opened for write should return -ETXTBSY"
5680
5681 test_43a() {
5682         test_mkdir $DIR/$tdir
5683         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5684         $DIR/$tdir/sleep 60 &
5685         SLEEP_PID=$!
5686         # Make sure exec of $tdir/sleep wins race with truncate
5687         sleep 1
5688         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5689         kill $SLEEP_PID
5690 }
5691 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5692
5693 test_43b() {
5694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5695
5696         test_mkdir $DIR/$tdir
5697         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5698         $DIR/$tdir/sleep 60 &
5699         SLEEP_PID=$!
5700         # Make sure exec of $tdir/sleep wins race with truncate
5701         sleep 1
5702         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5703         kill $SLEEP_PID
5704 }
5705 run_test 43b "truncate of file being executed should return -ETXTBSY"
5706
5707 test_43c() {
5708         local testdir="$DIR/$tdir"
5709         test_mkdir $testdir
5710         cp $SHELL $testdir/
5711         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5712                 ( cd $testdir && md5sum -c )
5713 }
5714 run_test 43c "md5sum of copy into lustre"
5715
5716 test_44A() { # was test_44
5717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5718
5719         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5720         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5721 }
5722 run_test 44A "zero length read from a sparse stripe"
5723
5724 test_44a() {
5725         local nstripe=$($LFS getstripe -c -d $DIR)
5726         [ -z "$nstripe" ] && skip "can't get stripe info"
5727         [[ $nstripe -gt $OSTCOUNT ]] &&
5728                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5729
5730         local stride=$($LFS getstripe -S -d $DIR)
5731         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5732                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5733         fi
5734
5735         OFFSETS="0 $((stride/2)) $((stride-1))"
5736         for offset in $OFFSETS; do
5737                 for i in $(seq 0 $((nstripe-1))); do
5738                         local GLOBALOFFSETS=""
5739                         # size in Bytes
5740                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5741                         local myfn=$DIR/d44a-$size
5742                         echo "--------writing $myfn at $size"
5743                         ll_sparseness_write $myfn $size ||
5744                                 error "ll_sparseness_write"
5745                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5746                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5747                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5748
5749                         for j in $(seq 0 $((nstripe-1))); do
5750                                 # size in Bytes
5751                                 size=$((((j + $nstripe )*$stride + $offset)))
5752                                 ll_sparseness_write $myfn $size ||
5753                                         error "ll_sparseness_write"
5754                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5755                         done
5756                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5757                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5758                         rm -f $myfn
5759                 done
5760         done
5761 }
5762 run_test 44a "test sparse pwrite ==============================="
5763
5764 dirty_osc_total() {
5765         tot=0
5766         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5767                 tot=$(($tot + $d))
5768         done
5769         echo $tot
5770 }
5771 do_dirty_record() {
5772         before=`dirty_osc_total`
5773         echo executing "\"$*\""
5774         eval $*
5775         after=`dirty_osc_total`
5776         echo before $before, after $after
5777 }
5778 test_45() {
5779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5780
5781         f="$DIR/f45"
5782         # Obtain grants from OST if it supports it
5783         echo blah > ${f}_grant
5784         stop_writeback
5785         sync
5786         do_dirty_record "echo blah > $f"
5787         [[ $before -eq $after ]] && error "write wasn't cached"
5788         do_dirty_record "> $f"
5789         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5790         do_dirty_record "echo blah > $f"
5791         [[ $before -eq $after ]] && error "write wasn't cached"
5792         do_dirty_record "sync"
5793         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5794         do_dirty_record "echo blah > $f"
5795         [[ $before -eq $after ]] && error "write wasn't cached"
5796         do_dirty_record "cancel_lru_locks osc"
5797         [[ $before -gt $after ]] ||
5798                 error "lock cancellation didn't lower dirty count"
5799         start_writeback
5800 }
5801 run_test 45 "osc io page accounting ============================"
5802
5803 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5804 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5805 # objects offset and an assert hit when an rpc was built with 1023's mapped
5806 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5807 test_46() {
5808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5809
5810         f="$DIR/f46"
5811         stop_writeback
5812         sync
5813         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5814         sync
5815         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5816         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5817         sync
5818         start_writeback
5819 }
5820 run_test 46 "dirtying a previously written page ================"
5821
5822 # test_47 is removed "Device nodes check" is moved to test_28
5823
5824 test_48a() { # bug 2399
5825         [ "$mds1_FSTYPE" = "zfs" ] &&
5826         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5827                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5828
5829         test_mkdir $DIR/$tdir
5830         cd $DIR/$tdir
5831         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5832         test_mkdir $DIR/$tdir
5833         touch foo || error "'touch foo' failed after recreating cwd"
5834         test_mkdir bar
5835         touch .foo || error "'touch .foo' failed after recreating cwd"
5836         test_mkdir .bar
5837         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5838         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5839         cd . || error "'cd .' failed after recreating cwd"
5840         mkdir . && error "'mkdir .' worked after recreating cwd"
5841         rmdir . && error "'rmdir .' worked after recreating cwd"
5842         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5843         cd .. || error "'cd ..' failed after recreating cwd"
5844 }
5845 run_test 48a "Access renamed working dir (should return errors)="
5846
5847 test_48b() { # bug 2399
5848         rm -rf $DIR/$tdir
5849         test_mkdir $DIR/$tdir
5850         cd $DIR/$tdir
5851         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5852         touch foo && error "'touch foo' worked after removing cwd"
5853         mkdir foo && error "'mkdir foo' worked after removing cwd"
5854         touch .foo && error "'touch .foo' worked after removing cwd"
5855         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5856         ls . > /dev/null && error "'ls .' worked after removing cwd"
5857         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5858         mkdir . && error "'mkdir .' worked after removing cwd"
5859         rmdir . && error "'rmdir .' worked after removing cwd"
5860         ln -s . foo && error "'ln -s .' worked after removing cwd"
5861         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5862 }
5863 run_test 48b "Access removed working dir (should return errors)="
5864
5865 test_48c() { # bug 2350
5866         #lctl set_param debug=-1
5867         #set -vx
5868         rm -rf $DIR/$tdir
5869         test_mkdir -p $DIR/$tdir/dir
5870         cd $DIR/$tdir/dir
5871         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5872         $TRACE touch foo && error "touch foo worked after removing cwd"
5873         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5874         touch .foo && error "touch .foo worked after removing cwd"
5875         mkdir .foo && error "mkdir .foo worked after removing cwd"
5876         $TRACE ls . && error "'ls .' worked after removing cwd"
5877         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5878         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5879         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5880         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5881         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5882 }
5883 run_test 48c "Access removed working subdir (should return errors)"
5884
5885 test_48d() { # bug 2350
5886         #lctl set_param debug=-1
5887         #set -vx
5888         rm -rf $DIR/$tdir
5889         test_mkdir -p $DIR/$tdir/dir
5890         cd $DIR/$tdir/dir
5891         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5892         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5893         $TRACE touch foo && error "'touch foo' worked after removing parent"
5894         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5895         touch .foo && error "'touch .foo' worked after removing parent"
5896         mkdir .foo && error "mkdir .foo worked after removing parent"
5897         $TRACE ls . && error "'ls .' worked after removing parent"
5898         $TRACE ls .. && error "'ls ..' worked after removing parent"
5899         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5900         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5901         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5902         true
5903 }
5904 run_test 48d "Access removed parent subdir (should return errors)"
5905
5906 test_48e() { # bug 4134
5907         #lctl set_param debug=-1
5908         #set -vx
5909         rm -rf $DIR/$tdir
5910         test_mkdir -p $DIR/$tdir/dir
5911         cd $DIR/$tdir/dir
5912         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5913         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5914         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5915         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5916         # On a buggy kernel addition of "touch foo" after cd .. will
5917         # produce kernel oops in lookup_hash_it
5918         touch ../foo && error "'cd ..' worked after recreate parent"
5919         cd $DIR
5920         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5921 }
5922 run_test 48e "Access to recreated parent subdir (should return errors)"
5923
5924 test_48f() {
5925         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5926                 skip "need MDS >= 2.13.55"
5927         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5928         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5929                 skip "needs different host for mdt1 mdt2"
5930         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5931
5932         $LFS mkdir -i0 $DIR/$tdir
5933         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5934
5935         for d in sub1 sub2 sub3; do
5936                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5937                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5938                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5939         done
5940
5941         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5942 }
5943 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5944
5945 test_49() { # LU-1030
5946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5947         remote_ost_nodsh && skip "remote OST with nodsh"
5948
5949         # get ost1 size - $FSNAME-OST0000
5950         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5951                 awk '{ print $4 }')
5952         # write 800M at maximum
5953         [[ $ost1_size -lt 2 ]] && ost1_size=2
5954         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5955
5956         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5957         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5958         local dd_pid=$!
5959
5960         # change max_pages_per_rpc while writing the file
5961         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5962         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5963         # loop until dd process exits
5964         while ps ax -opid | grep -wq $dd_pid; do
5965                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5966                 sleep $((RANDOM % 5 + 1))
5967         done
5968         # restore original max_pages_per_rpc
5969         $LCTL set_param $osc1_mppc=$orig_mppc
5970         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5971 }
5972 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5973
5974 test_50() {
5975         # bug 1485
5976         test_mkdir $DIR/$tdir
5977         cd $DIR/$tdir
5978         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5979 }
5980 run_test 50 "special situations: /proc symlinks  ==============="
5981
5982 test_51a() {    # was test_51
5983         # bug 1516 - create an empty entry right after ".." then split dir
5984         test_mkdir -c1 $DIR/$tdir
5985         touch $DIR/$tdir/foo
5986         $MCREATE $DIR/$tdir/bar
5987         rm $DIR/$tdir/foo
5988         createmany -m $DIR/$tdir/longfile 201
5989         FNUM=202
5990         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5991                 $MCREATE $DIR/$tdir/longfile$FNUM
5992                 FNUM=$(($FNUM + 1))
5993                 echo -n "+"
5994         done
5995         echo
5996         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5997 }
5998 run_test 51a "special situations: split htree with empty entry =="
5999
6000 cleanup_print_lfs_df () {
6001         trap 0
6002         $LFS df
6003         $LFS df -i
6004 }
6005
6006 test_51b() {
6007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6008
6009         local dir=$DIR/$tdir
6010         local nrdirs=$((65536 + 100))
6011
6012         # cleanup the directory
6013         rm -fr $dir
6014
6015         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6016
6017         $LFS df
6018         $LFS df -i
6019         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6020         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6021         [[ $numfree -lt $nrdirs ]] &&
6022                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6023
6024         # need to check free space for the directories as well
6025         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6026         numfree=$(( blkfree / $(fs_inode_ksize) ))
6027         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6028
6029         trap cleanup_print_lfs_df EXIT
6030
6031         # create files
6032         createmany -d $dir/d $nrdirs || {
6033                 unlinkmany $dir/d $nrdirs
6034                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6035         }
6036
6037         # really created :
6038         nrdirs=$(ls -U $dir | wc -l)
6039
6040         # unlink all but 100 subdirectories, then check it still works
6041         local left=100
6042         local delete=$((nrdirs - left))
6043
6044         $LFS df
6045         $LFS df -i
6046
6047         # for ldiskfs the nlink count should be 1, but this is OSD specific
6048         # and so this is listed for informational purposes only
6049         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6050         unlinkmany -d $dir/d $delete ||
6051                 error "unlink of first $delete subdirs failed"
6052
6053         echo "nlink between: $(stat -c %h $dir)"
6054         local found=$(ls -U $dir | wc -l)
6055         [ $found -ne $left ] &&
6056                 error "can't find subdirs: found only $found, expected $left"
6057
6058         unlinkmany -d $dir/d $delete $left ||
6059                 error "unlink of second $left subdirs failed"
6060         # regardless of whether the backing filesystem tracks nlink accurately
6061         # or not, the nlink count shouldn't be more than "." and ".." here
6062         local after=$(stat -c %h $dir)
6063         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6064                 echo "nlink after: $after"
6065
6066         cleanup_print_lfs_df
6067 }
6068 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6069
6070 test_51d_sub() {
6071         local stripecount=$1
6072         local nfiles=$2
6073
6074         log "create files with stripecount=$stripecount"
6075         $LFS setstripe -C $stripecount $DIR/$tdir
6076         createmany -o $DIR/$tdir/t- $nfiles
6077         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6078         for ((n = 0; n < $OSTCOUNT; n++)); do
6079                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6080                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6081                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6082                             '($1 == '$n') { objs += 1 } \
6083                             END { printf("%0.0f", objs) }')
6084                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6085         done
6086         unlinkmany $DIR/$tdir/t- $nfiles
6087         rm  -f $TMP/$tfile
6088
6089         local nlast
6090         local min=4
6091         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6092
6093         # For some combinations of stripecount and OSTCOUNT current code
6094         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6095         # than others. Rather than skipping this test entirely, check that
6096         # and keep testing to ensure imbalance does not get worse. LU-15282
6097         (( (OSTCOUNT == 6 && stripecount == 4) ||
6098            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6099            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6100         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6101                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6102                         { $LFS df && $LFS df -i &&
6103                         error "stripecount=$stripecount: " \
6104                               "OST $n has fewer objects vs. OST $nlast " \
6105                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6106                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6107                         { $LFS df && $LFS df -i &&
6108                         error "stripecount=$stripecount: " \
6109                               "OST $n has more objects vs. OST $nlast " \
6110                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6111
6112                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6113                         { $LFS df && $LFS df -i &&
6114                         error "stripecount=$stripecount: " \
6115                               "OST $n has fewer #0 objects vs. OST $nlast " \
6116                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6117                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6118                         { $LFS df && $LFS df -i &&
6119                         error "stripecount=$stripecount: " \
6120                               "OST $n has more #0 objects vs. OST $nlast " \
6121                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6122         done
6123 }
6124
6125 test_51d() {
6126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6127         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6128
6129         local stripecount
6130         local per_ost=100
6131         local nfiles=$((per_ost * OSTCOUNT))
6132         local mdts=$(comma_list $(mdts_nodes))
6133         local param="osp.*.create_count"
6134         local qos_old=$(do_facet mds1 \
6135                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6136
6137         do_nodes $mdts \
6138                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6139         stack_trap "do_nodes $mdts \
6140                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6141
6142         test_mkdir $DIR/$tdir
6143         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6144         (( dirstripes > 0 )) || dirstripes=1
6145
6146         # Ensure enough OST objects precreated for tests to pass without
6147         # running out of objects.  This is an LOV r-r OST algorithm test,
6148         # not an OST object precreation test.
6149         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6150         (( old >= nfiles )) ||
6151         {
6152                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6153
6154                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6155                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6156
6157                 # trigger precreation from all MDTs for all OSTs
6158                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6159                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6160                 done
6161         }
6162
6163         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6164                 sleep 8  # allow object precreation to catch up
6165                 test_51d_sub $stripecount $nfiles
6166         done
6167 }
6168 run_test 51d "check LOV round-robin OST object distribution"
6169
6170 test_51e() {
6171         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6172                 skip_env "ldiskfs only test"
6173         fi
6174
6175         test_mkdir -c1 $DIR/$tdir
6176         test_mkdir -c1 $DIR/$tdir/d0
6177
6178         touch $DIR/$tdir/d0/foo
6179         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6180                 error "file exceed 65000 nlink limit!"
6181         unlinkmany $DIR/$tdir/d0/f- 65001
6182         return 0
6183 }
6184 run_test 51e "check file nlink limit"
6185
6186 test_51f() {
6187         test_mkdir $DIR/$tdir
6188
6189         local max=100000
6190         local ulimit_old=$(ulimit -n)
6191         local spare=20 # number of spare fd's for scripts/libraries, etc.
6192         local mdt=$($LFS getstripe -m $DIR/$tdir)
6193         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6194
6195         echo "MDT$mdt numfree=$numfree, max=$max"
6196         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6197         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6198                 while ! ulimit -n $((numfree + spare)); do
6199                         numfree=$((numfree * 3 / 4))
6200                 done
6201                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6202         else
6203                 echo "left ulimit at $ulimit_old"
6204         fi
6205
6206         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6207                 unlinkmany $DIR/$tdir/f $numfree
6208                 error "create+open $numfree files in $DIR/$tdir failed"
6209         }
6210         ulimit -n $ulimit_old
6211
6212         # if createmany exits at 120s there will be fewer than $numfree files
6213         unlinkmany $DIR/$tdir/f $numfree || true
6214 }
6215 run_test 51f "check many open files limit"
6216
6217 test_52a() {
6218         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6219         test_mkdir $DIR/$tdir
6220         touch $DIR/$tdir/foo
6221         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6222         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6223         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6224         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6225         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6226                                         error "link worked"
6227         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6228         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6229         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6230                                                      error "lsattr"
6231         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6232         cp -r $DIR/$tdir $TMP/
6233         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6234 }
6235 run_test 52a "append-only flag test (should return errors)"
6236
6237 test_52b() {
6238         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6239         test_mkdir $DIR/$tdir
6240         touch $DIR/$tdir/foo
6241         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6242         cat test > $DIR/$tdir/foo && error "cat test worked"
6243         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6244         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6245         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6246                                         error "link worked"
6247         echo foo >> $DIR/$tdir/foo && error "echo worked"
6248         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6249         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6250         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6251         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6252                                                         error "lsattr"
6253         chattr -i $DIR/$tdir/foo || error "chattr failed"
6254
6255         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6256 }
6257 run_test 52b "immutable flag test (should return errors) ======="
6258
6259 test_53() {
6260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6261         remote_mds_nodsh && skip "remote MDS with nodsh"
6262         remote_ost_nodsh && skip "remote OST with nodsh"
6263
6264         local param
6265         local param_seq
6266         local ostname
6267         local mds_last
6268         local mds_last_seq
6269         local ost_last
6270         local ost_last_seq
6271         local ost_last_id
6272         local ostnum
6273         local node
6274         local found=false
6275         local support_last_seq=true
6276
6277         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6278                 support_last_seq=false
6279
6280         # only test MDT0000
6281         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6282         local value
6283         for value in $(do_facet $SINGLEMDS \
6284                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6285                 param=$(echo ${value[0]} | cut -d "=" -f1)
6286                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6287
6288                 if $support_last_seq; then
6289                         param_seq=$(echo $param |
6290                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6291                         mds_last_seq=$(do_facet $SINGLEMDS \
6292                                        $LCTL get_param -n $param_seq)
6293                 fi
6294                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6295
6296                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6297                 node=$(facet_active_host ost$((ostnum+1)))
6298                 param="obdfilter.$ostname.last_id"
6299                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6300                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6301                         ost_last_id=$ost_last
6302
6303                         if $support_last_seq; then
6304                                 ost_last_id=$(echo $ost_last |
6305                                               awk -F':' '{print $2}' |
6306                                               sed -e "s/^0x//g")
6307                                 ost_last_seq=$(echo $ost_last |
6308                                                awk -F':' '{print $1}')
6309                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6310                         fi
6311
6312                         if [[ $ost_last_id != $mds_last ]]; then
6313                                 error "$ost_last_id != $mds_last"
6314                         else
6315                                 found=true
6316                                 break
6317                         fi
6318                 done
6319         done
6320         $found || error "can not match last_seq/last_id for $mdtosc"
6321         return 0
6322 }
6323 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6324
6325 test_54a() {
6326         $SOCKETSERVER $DIR/socket ||
6327                 error "$SOCKETSERVER $DIR/socket failed: $?"
6328         $SOCKETCLIENT $DIR/socket ||
6329                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6330         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6331 }
6332 run_test 54a "unix domain socket test"
6333
6334 test_54b() {
6335         f="$DIR/f54b"
6336         mknod $f c 1 3
6337         chmod 0666 $f
6338         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6339 }
6340 run_test 54b "char device works in lustre ======================"
6341
6342 find_loop_dev() {
6343         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6344         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6345         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6346
6347         for i in $(seq 3 7); do
6348                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6349                 LOOPDEV=$LOOPBASE$i
6350                 LOOPNUM=$i
6351                 break
6352         done
6353 }
6354
6355 cleanup_54c() {
6356         local rc=0
6357         loopdev="$DIR/loop54c"
6358
6359         trap 0
6360         $UMOUNT $DIR/$tdir || rc=$?
6361         losetup -d $loopdev || true
6362         losetup -d $LOOPDEV || true
6363         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6364         return $rc
6365 }
6366
6367 test_54c() {
6368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6369
6370         loopdev="$DIR/loop54c"
6371
6372         find_loop_dev
6373         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6374         trap cleanup_54c EXIT
6375         mknod $loopdev b 7 $LOOPNUM
6376         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6377         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6378         losetup $loopdev $DIR/$tfile ||
6379                 error "can't set up $loopdev for $DIR/$tfile"
6380         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6381         test_mkdir $DIR/$tdir
6382         mount -t ext2 $loopdev $DIR/$tdir ||
6383                 error "error mounting $loopdev on $DIR/$tdir"
6384         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6385                 error "dd write"
6386         df $DIR/$tdir
6387         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6388                 error "dd read"
6389         cleanup_54c
6390 }
6391 run_test 54c "block device works in lustre ====================="
6392
6393 test_54d() {
6394         local pipe="$DIR/$tfile.pipe"
6395         local string="aaaaaa"
6396
6397         mknod $pipe p
6398         echo -n "$string" > $pipe &
6399         local result=$(cat $pipe)
6400         [[ "$result" == "$string" ]] || error "$result != $string"
6401 }
6402 run_test 54d "fifo device works in lustre ======================"
6403
6404 test_54e() {
6405         f="$DIR/f54e"
6406         string="aaaaaa"
6407         cp -aL /dev/console $f
6408         echo $string > $f || error "echo $string to $f failed"
6409 }
6410 run_test 54e "console/tty device works in lustre ======================"
6411
6412 test_55a() {
6413         local dev_path="/sys/kernel/debug/lustre/devices"
6414
6415         load_module kunit/obd_test verbose=2 || error "load_module failed"
6416
6417         # This must be run in iteractive mode, since attach and setup
6418         # are stateful
6419         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6420                 attach obd_test obd_name obd_uuid
6421                 setup obd_test
6422         EOF"
6423
6424         echo "Devices:"
6425         cat "$dev_path" | tail -n 10
6426
6427         $LCTL --device "obd_name" cleanup
6428         $LCTL --device "obd_name" detach
6429
6430         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6431                 error "OBD unit test failed"
6432
6433         rmmod -v obd_test ||
6434                 error "rmmod failed (may trigger a failure in a later test)"
6435 }
6436 run_test 55a "OBD device life cycle unit tests"
6437
6438 test_55b() {
6439         local dev_path="/sys/kernel/debug/lustre/devices"
6440         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6441
6442         # Set up a large number of devices, using the number
6443         # that can be set up in about a minute (based on prior
6444         # testing). We don't want to run this test forever.
6445         local num_dev_to_create="$(( 24000 - $dev_count))"
6446
6447         load_module kunit/obd_test || error "load_module failed"
6448
6449         local start=$SECONDS
6450
6451         # This must be run in iteractive mode, since attach and setup
6452         # are stateful
6453         for ((i = 1; i <= num_dev_to_create; i++)); do
6454                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6455                 echo "setup obd_test_$i"
6456         done | $LCTL || error "OBD device creation failed"
6457
6458         echo "Load time: $((SECONDS - start))"
6459         echo "Devices:"
6460         cat "$dev_path" | tail -n 10
6461
6462         for ((i = 1; i <= num_dev_to_create; i++)); do
6463                 echo "--device obd_name_$i cleanup"
6464                 echo "--device obd_name_$i detach"
6465         done | $LCTL || error "OBD device cleanup failed"
6466
6467         echo "Unload time: $((SECONDS - start))"
6468
6469         rmmod -v obd_test ||
6470                 error "rmmod failed (may trigger a failure in a later test)"
6471 }
6472 run_test 55b "Load and unload max OBD devices"
6473
6474 test_56a() {
6475         local numfiles=3
6476         local numdirs=2
6477         local dir=$DIR/$tdir
6478
6479         rm -rf $dir
6480         test_mkdir -p $dir/dir
6481         for i in $(seq $numfiles); do
6482                 touch $dir/file$i
6483                 touch $dir/dir/file$i
6484         done
6485
6486         local numcomp=$($LFS getstripe --component-count $dir)
6487
6488         [[ $numcomp == 0 ]] && numcomp=1
6489
6490         # test lfs getstripe with --recursive
6491         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6492
6493         [[ $filenum -eq $((numfiles * 2)) ]] ||
6494                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6495         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6496         [[ $filenum -eq $numfiles ]] ||
6497                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6498         echo "$LFS getstripe showed obdidx or l_ost_idx"
6499
6500         # test lfs getstripe with file instead of dir
6501         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6502         [[ $filenum -eq 1 ]] ||
6503                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6504         echo "$LFS getstripe file1 passed"
6505
6506         #test lfs getstripe with --verbose
6507         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6508         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6509                 error "$LFS getstripe --verbose $dir: "\
6510                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6511         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6512                 error "$LFS getstripe $dir: showed lmm_magic"
6513
6514         #test lfs getstripe with -v prints lmm_fid
6515         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6516         local countfids=$(((numdirs + numfiles) * numcomp))
6517         [[ $filenum -eq $countfids ]] ||
6518                 error "$LFS getstripe -v $dir: "\
6519                       "got $filenum want $countfids lmm_fid"
6520         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6521                 error "$LFS getstripe $dir: showed lmm_fid by default"
6522         echo "$LFS getstripe --verbose passed"
6523
6524         #check for FID information
6525         local fid1=$($LFS getstripe --fid $dir/file1)
6526         local fid2=$($LFS getstripe --verbose $dir/file1 |
6527                      awk '/lmm_fid: / { print $2; exit; }')
6528         local fid3=$($LFS path2fid $dir/file1)
6529
6530         [ "$fid1" != "$fid2" ] &&
6531                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6532         [ "$fid1" != "$fid3" ] &&
6533                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6534         echo "$LFS getstripe --fid passed"
6535
6536         #test lfs getstripe with --obd
6537         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6538                 error "$LFS getstripe --obd wrong_uuid: should return error"
6539
6540         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6541
6542         local ostidx=1
6543         local obduuid=$(ostuuid_from_index $ostidx)
6544         local found=$($LFS getstripe -r --obd $obduuid $dir |
6545                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6546
6547         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6548         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6549                 ((filenum--))
6550         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6551                 ((filenum--))
6552
6553         [[ $found -eq $filenum ]] ||
6554                 error "$LFS getstripe --obd: found $found expect $filenum"
6555         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6556                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6557                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6558                 error "$LFS getstripe --obd: should not show file on other obd"
6559         echo "$LFS getstripe --obd passed"
6560 }
6561 run_test 56a "check $LFS getstripe"
6562
6563 test_56b() {
6564         local dir=$DIR/$tdir
6565         local numdirs=3
6566
6567         test_mkdir $dir
6568         for i in $(seq $numdirs); do
6569                 test_mkdir $dir/dir$i
6570         done
6571
6572         # test lfs getdirstripe default mode is non-recursion, which is
6573         # different from lfs getstripe
6574         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6575
6576         [[ $dircnt -eq 1 ]] ||
6577                 error "$LFS getdirstripe: found $dircnt, not 1"
6578         dircnt=$($LFS getdirstripe --recursive $dir |
6579                 grep -c lmv_stripe_count)
6580         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6581                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6582 }
6583 run_test 56b "check $LFS getdirstripe"
6584
6585 test_56bb() {
6586         verify_yaml_available || skip_env "YAML verification not installed"
6587         local output_file=$DIR/$tfile.out
6588
6589         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6590
6591         cat $output_file
6592         cat $output_file | verify_yaml || error "layout is not valid YAML"
6593 }
6594 run_test 56bb "check $LFS getdirstripe layout is YAML"
6595
6596 test_56c() {
6597         remote_ost_nodsh && skip "remote OST with nodsh"
6598
6599         local ost_idx=0
6600         local ost_name=$(ostname_from_index $ost_idx)
6601         local old_status=$(ost_dev_status $ost_idx)
6602         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6603
6604         [[ -z "$old_status" ]] ||
6605                 skip_env "OST $ost_name is in $old_status status"
6606
6607         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6608         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6609                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6610         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6611                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6612                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6613         fi
6614
6615         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6616                 error "$LFS df -v showing inactive devices"
6617         sleep_maxage
6618
6619         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6620
6621         [[ "$new_status" =~ "D" ]] ||
6622                 error "$ost_name status is '$new_status', missing 'D'"
6623         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6624                 [[ "$new_status" =~ "N" ]] ||
6625                         error "$ost_name status is '$new_status', missing 'N'"
6626         fi
6627         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6628                 [[ "$new_status" =~ "f" ]] ||
6629                         error "$ost_name status is '$new_status', missing 'f'"
6630         fi
6631
6632         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6633         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6634                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6635         [[ -z "$p" ]] && restore_lustre_params < $p || true
6636         sleep_maxage
6637
6638         new_status=$(ost_dev_status $ost_idx)
6639         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6640                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6641         # can't check 'f' as devices may actually be on flash
6642 }
6643 run_test 56c "check 'lfs df' showing device status"
6644
6645 test_56d() {
6646         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6647         local osts=$($LFS df -v $MOUNT | grep -c OST)
6648
6649         $LFS df $MOUNT
6650
6651         (( mdts == MDSCOUNT )) ||
6652                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6653         (( osts == OSTCOUNT )) ||
6654                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6655 }
6656 run_test 56d "'lfs df -v' prints only configured devices"
6657
6658 test_56e() {
6659         err_enoent=2 # No such file or directory
6660         err_eopnotsupp=95 # Operation not supported
6661
6662         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6663         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6664
6665         # Check for handling of path not exists
6666         output=$($LFS df $enoent_mnt 2>&1)
6667         ret=$?
6668
6669         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6670         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6671                 error "expect failure $err_enoent, not $ret"
6672
6673         # Check for handling of non-Lustre FS
6674         output=$($LFS df $notsup_mnt)
6675         ret=$?
6676
6677         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6678         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6679                 error "expect success $err_eopnotsupp, not $ret"
6680
6681         # Check for multiple LustreFS argument
6682         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6683         ret=$?
6684
6685         [[ $output -eq 3 && $ret -eq 0 ]] ||
6686                 error "expect success 3, not $output, rc = $ret"
6687
6688         # Check for correct non-Lustre FS handling among multiple
6689         # LustreFS argument
6690         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6691                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6692         ret=$?
6693
6694         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6695                 error "expect success 2, not $output, rc = $ret"
6696 }
6697 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6698
6699 NUMFILES=3
6700 NUMDIRS=3
6701 setup_56() {
6702         local local_tdir="$1"
6703         local local_numfiles="$2"
6704         local local_numdirs="$3"
6705         local dir_params="$4"
6706         local dir_stripe_params="$5"
6707
6708         if [ ! -d "$local_tdir" ] ; then
6709                 test_mkdir -p $dir_stripe_params $local_tdir
6710                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6711                 for i in $(seq $local_numfiles) ; do
6712                         touch $local_tdir/file$i
6713                 done
6714                 for i in $(seq $local_numdirs) ; do
6715                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6716                         for j in $(seq $local_numfiles) ; do
6717                                 touch $local_tdir/dir$i/file$j
6718                         done
6719                 done
6720         fi
6721 }
6722
6723 setup_56_special() {
6724         local local_tdir=$1
6725         local local_numfiles=$2
6726         local local_numdirs=$3
6727
6728         setup_56 $local_tdir $local_numfiles $local_numdirs
6729
6730         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6731                 for i in $(seq $local_numfiles) ; do
6732                         mknod $local_tdir/loop${i}b b 7 $i
6733                         mknod $local_tdir/null${i}c c 1 3
6734                         ln -s $local_tdir/file1 $local_tdir/link${i}
6735                 done
6736                 for i in $(seq $local_numdirs) ; do
6737                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6738                         mknod $local_tdir/dir$i/null${i}c c 1 3
6739                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6740                 done
6741         fi
6742 }
6743
6744 test_56g() {
6745         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6746         local expected=$(($NUMDIRS + 2))
6747
6748         setup_56 $dir $NUMFILES $NUMDIRS
6749
6750         # test lfs find with -name
6751         for i in $(seq $NUMFILES) ; do
6752                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6753
6754                 [ $nums -eq $expected ] ||
6755                         error "lfs find -name '*$i' $dir wrong: "\
6756                               "found $nums, expected $expected"
6757         done
6758 }
6759 run_test 56g "check lfs find -name"
6760
6761 test_56h() {
6762         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6763         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6764
6765         setup_56 $dir $NUMFILES $NUMDIRS
6766
6767         # test lfs find with ! -name
6768         for i in $(seq $NUMFILES) ; do
6769                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6770
6771                 [ $nums -eq $expected ] ||
6772                         error "lfs find ! -name '*$i' $dir wrong: "\
6773                               "found $nums, expected $expected"
6774         done
6775 }
6776 run_test 56h "check lfs find ! -name"
6777
6778 test_56i() {
6779         local dir=$DIR/$tdir
6780
6781         test_mkdir $dir
6782
6783         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6784         local out=$($cmd)
6785
6786         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6787 }
6788 run_test 56i "check 'lfs find -ost UUID' skips directories"
6789
6790 test_56j() {
6791         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6792
6793         setup_56_special $dir $NUMFILES $NUMDIRS
6794
6795         local expected=$((NUMDIRS + 1))
6796         local cmd="$LFS find -type d $dir"
6797         local nums=$($cmd | wc -l)
6798
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801 }
6802 run_test 56j "check lfs find -type d"
6803
6804 test_56k() {
6805         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6806
6807         setup_56_special $dir $NUMFILES $NUMDIRS
6808
6809         local expected=$(((NUMDIRS + 1) * NUMFILES))
6810         local cmd="$LFS find -type f $dir"
6811         local nums=$($cmd | wc -l)
6812
6813         [ $nums -eq $expected ] ||
6814                 error "'$cmd' wrong: found $nums, expected $expected"
6815 }
6816 run_test 56k "check lfs find -type f"
6817
6818 test_56l() {
6819         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6820
6821         setup_56_special $dir $NUMFILES $NUMDIRS
6822
6823         local expected=$((NUMDIRS + NUMFILES))
6824         local cmd="$LFS find -type b $dir"
6825         local nums=$($cmd | wc -l)
6826
6827         [ $nums -eq $expected ] ||
6828                 error "'$cmd' wrong: found $nums, expected $expected"
6829 }
6830 run_test 56l "check lfs find -type b"
6831
6832 test_56m() {
6833         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6834
6835         setup_56_special $dir $NUMFILES $NUMDIRS
6836
6837         local expected=$((NUMDIRS + NUMFILES))
6838         local cmd="$LFS find -type c $dir"
6839         local nums=$($cmd | wc -l)
6840         [ $nums -eq $expected ] ||
6841                 error "'$cmd' wrong: found $nums, expected $expected"
6842 }
6843 run_test 56m "check lfs find -type c"
6844
6845 test_56n() {
6846         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6847         setup_56_special $dir $NUMFILES $NUMDIRS
6848
6849         local expected=$((NUMDIRS + NUMFILES))
6850         local cmd="$LFS find -type l $dir"
6851         local nums=$($cmd | wc -l)
6852
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855 }
6856 run_test 56n "check lfs find -type l"
6857
6858 test_56o() {
6859         local dir=$DIR/$tdir
6860
6861         setup_56 $dir $NUMFILES $NUMDIRS
6862         utime $dir/file1 > /dev/null || error "utime (1)"
6863         utime $dir/file2 > /dev/null || error "utime (2)"
6864         utime $dir/dir1 > /dev/null || error "utime (3)"
6865         utime $dir/dir2 > /dev/null || error "utime (4)"
6866         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6867         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6868
6869         local expected=4
6870         local nums=$($LFS find -mtime +0 $dir | wc -l)
6871
6872         [ $nums -eq $expected ] ||
6873                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6874
6875         expected=12
6876         cmd="$LFS find -mtime 0 $dir"
6877         nums=$($cmd | wc -l)
6878         [ $nums -eq $expected ] ||
6879                 error "'$cmd' wrong: found $nums, expected $expected"
6880 }
6881 run_test 56o "check lfs find -mtime for old files"
6882
6883 test_56ob() {
6884         local dir=$DIR/$tdir
6885         local expected=1
6886         local count=0
6887
6888         # just to make sure there is something that won't be found
6889         test_mkdir $dir
6890         touch $dir/$tfile.now
6891
6892         for age in year week day hour min; do
6893                 count=$((count + 1))
6894
6895                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6896                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6897                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6898
6899                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6900                 local nums=$($cmd | wc -l)
6901                 [ $nums -eq $expected ] ||
6902                         error "'$cmd' wrong: found $nums, expected $expected"
6903
6904                 cmd="$LFS find $dir -atime $count${age:0:1}"
6905                 nums=$($cmd | wc -l)
6906                 [ $nums -eq $expected ] ||
6907                         error "'$cmd' wrong: found $nums, expected $expected"
6908         done
6909
6910         sleep 2
6911         cmd="$LFS find $dir -ctime +1s -type f"
6912         nums=$($cmd | wc -l)
6913         (( $nums == $count * 2 + 1)) ||
6914                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6915 }
6916 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6917
6918 test_newerXY_base() {
6919         local x=$1
6920         local y=$2
6921         local dir=$DIR/$tdir
6922         local ref
6923         local negref
6924
6925         if [ $y == "t" ]; then
6926                 if [ $x == "b" ]; then
6927                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6928                 else
6929                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6930                 fi
6931         else
6932                 ref=$DIR/$tfile.newer.$x$y
6933                 touch $ref || error "touch $ref failed"
6934         fi
6935
6936         echo "before = $ref"
6937         sleep 2
6938         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6939         sleep 2
6940         if [ $y == "t" ]; then
6941                 if [ $x == "b" ]; then
6942                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6943                 else
6944                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6945                 fi
6946         else
6947                 negref=$DIR/$tfile.negnewer.$x$y
6948                 touch $negref || error "touch $negref failed"
6949         fi
6950
6951         echo "after = $negref"
6952         local cmd="$LFS find $dir -newer$x$y $ref"
6953         local nums=$(eval $cmd | wc -l)
6954         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6955
6956         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6957                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6958
6959         cmd="$LFS find $dir ! -newer$x$y $negref"
6960         nums=$(eval $cmd | wc -l)
6961         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6962                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6963
6964         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6965         nums=$(eval $cmd | wc -l)
6966         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6967                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6968
6969         rm -rf $DIR/*
6970 }
6971
6972 test_56oc() {
6973         test_newerXY_base "a" "a"
6974         test_newerXY_base "a" "m"
6975         test_newerXY_base "a" "c"
6976         test_newerXY_base "m" "a"
6977         test_newerXY_base "m" "m"
6978         test_newerXY_base "m" "c"
6979         test_newerXY_base "c" "a"
6980         test_newerXY_base "c" "m"
6981         test_newerXY_base "c" "c"
6982
6983         test_newerXY_base "a" "t"
6984         test_newerXY_base "m" "t"
6985         test_newerXY_base "c" "t"
6986
6987         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
6988            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6989                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
6990
6991         test_newerXY_base "b" "b"
6992         test_newerXY_base "b" "t"
6993 }
6994 run_test 56oc "check lfs find -newerXY work"
6995
6996 test_56od() {
6997         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
6998                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
6999
7000         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7001                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7002
7003         local dir=$DIR/$tdir
7004         local ref=$DIR/$tfile.ref
7005         local negref=$DIR/$tfile.negref
7006
7007         mkdir $dir || error "mkdir $dir failed"
7008         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7009         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7010         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7011         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7012         touch $ref || error "touch $ref failed"
7013         # sleep 3 seconds at least
7014         sleep 3
7015
7016         local before=$(do_facet mds1 date +%s)
7017         local skew=$(($(date +%s) - before + 1))
7018
7019         if (( skew < 0 && skew > -5 )); then
7020                 sleep $((0 - skew + 1))
7021                 skew=0
7022         fi
7023
7024         # Set the dir stripe params to limit files all on MDT0,
7025         # otherwise we need to calc the max clock skew between
7026         # the client and MDTs.
7027         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7028         sleep 2
7029         touch $negref || error "touch $negref failed"
7030
7031         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7032         local nums=$($cmd | wc -l)
7033         local expected=$(((NUMFILES + 1) * NUMDIRS))
7034
7035         [ $nums -eq $expected ] ||
7036                 error "'$cmd' wrong: found $nums, expected $expected"
7037
7038         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7039         nums=$($cmd | wc -l)
7040         expected=$((NUMFILES + 1))
7041         [ $nums -eq $expected ] ||
7042                 error "'$cmd' wrong: found $nums, expected $expected"
7043
7044         [ $skew -lt 0 ] && return
7045
7046         local after=$(do_facet mds1 date +%s)
7047         local age=$((after - before + 1 + skew))
7048
7049         cmd="$LFS find $dir -btime -${age}s -type f"
7050         nums=$($cmd | wc -l)
7051         expected=$(((NUMFILES + 1) * NUMDIRS))
7052
7053         echo "Clock skew between client and server: $skew, age:$age"
7054         [ $nums -eq $expected ] ||
7055                 error "'$cmd' wrong: found $nums, expected $expected"
7056
7057         expected=$(($NUMDIRS + 1))
7058         cmd="$LFS find $dir -btime -${age}s -type d"
7059         nums=$($cmd | wc -l)
7060         [ $nums -eq $expected ] ||
7061                 error "'$cmd' wrong: found $nums, expected $expected"
7062         rm -f $ref $negref || error "Failed to remove $ref $negref"
7063 }
7064 run_test 56od "check lfs find -btime with units"
7065
7066 test_56p() {
7067         [ $RUNAS_ID -eq $UID ] &&
7068                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7069
7070         local dir=$DIR/$tdir
7071
7072         setup_56 $dir $NUMFILES $NUMDIRS
7073         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7074
7075         local expected=$NUMFILES
7076         local cmd="$LFS find -uid $RUNAS_ID $dir"
7077         local nums=$($cmd | wc -l)
7078
7079         [ $nums -eq $expected ] ||
7080                 error "'$cmd' wrong: found $nums, expected $expected"
7081
7082         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7083         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7084         nums=$($cmd | wc -l)
7085         [ $nums -eq $expected ] ||
7086                 error "'$cmd' wrong: found $nums, expected $expected"
7087 }
7088 run_test 56p "check lfs find -uid and ! -uid"
7089
7090 test_56q() {
7091         [ $RUNAS_ID -eq $UID ] &&
7092                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7093
7094         local dir=$DIR/$tdir
7095
7096         setup_56 $dir $NUMFILES $NUMDIRS
7097         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7098
7099         local expected=$NUMFILES
7100         local cmd="$LFS find -gid $RUNAS_GID $dir"
7101         local nums=$($cmd | wc -l)
7102
7103         [ $nums -eq $expected ] ||
7104                 error "'$cmd' wrong: found $nums, expected $expected"
7105
7106         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7107         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7108         nums=$($cmd | wc -l)
7109         [ $nums -eq $expected ] ||
7110                 error "'$cmd' wrong: found $nums, expected $expected"
7111 }
7112 run_test 56q "check lfs find -gid and ! -gid"
7113
7114 test_56r() {
7115         local dir=$DIR/$tdir
7116
7117         setup_56 $dir $NUMFILES $NUMDIRS
7118
7119         local expected=12
7120         local cmd="$LFS find -size 0 -type f -lazy $dir"
7121         local nums=$($cmd | wc -l)
7122
7123         [ $nums -eq $expected ] ||
7124                 error "'$cmd' wrong: found $nums, expected $expected"
7125         cmd="$LFS find -size 0 -type f $dir"
7126         nums=$($cmd | wc -l)
7127         [ $nums -eq $expected ] ||
7128                 error "'$cmd' wrong: found $nums, expected $expected"
7129
7130         expected=0
7131         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7132         nums=$($cmd | wc -l)
7133         [ $nums -eq $expected ] ||
7134                 error "'$cmd' wrong: found $nums, expected $expected"
7135         cmd="$LFS find ! -size 0 -type f $dir"
7136         nums=$($cmd | wc -l)
7137         [ $nums -eq $expected ] ||
7138                 error "'$cmd' wrong: found $nums, expected $expected"
7139
7140         echo "test" > $dir/$tfile
7141         echo "test2" > $dir/$tfile.2 && sync
7142         expected=1
7143         cmd="$LFS find -size 5c -type f -lazy $dir"
7144         nums=$($cmd | wc -l)
7145         [ $nums -eq $expected ] ||
7146                 error "'$cmd' wrong: found $nums, expected $expected"
7147         cmd="$LFS find -size 5c -type f $dir"
7148         nums=$($cmd | wc -l)
7149         [ $nums -eq $expected ] ||
7150                 error "'$cmd' wrong: found $nums, expected $expected"
7151
7152         expected=1
7153         cmd="$LFS find -size +5c -type f -lazy $dir"
7154         nums=$($cmd | wc -l)
7155         [ $nums -eq $expected ] ||
7156                 error "'$cmd' wrong: found $nums, expected $expected"
7157         cmd="$LFS find -size +5c -type f $dir"
7158         nums=$($cmd | wc -l)
7159         [ $nums -eq $expected ] ||
7160                 error "'$cmd' wrong: found $nums, expected $expected"
7161
7162         expected=2
7163         cmd="$LFS find -size +0 -type f -lazy $dir"
7164         nums=$($cmd | wc -l)
7165         [ $nums -eq $expected ] ||
7166                 error "'$cmd' wrong: found $nums, expected $expected"
7167         cmd="$LFS find -size +0 -type f $dir"
7168         nums=$($cmd | wc -l)
7169         [ $nums -eq $expected ] ||
7170                 error "'$cmd' wrong: found $nums, expected $expected"
7171
7172         expected=2
7173         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7174         nums=$($cmd | wc -l)
7175         [ $nums -eq $expected ] ||
7176                 error "'$cmd' wrong: found $nums, expected $expected"
7177         cmd="$LFS find ! -size -5c -type f $dir"
7178         nums=$($cmd | wc -l)
7179         [ $nums -eq $expected ] ||
7180                 error "'$cmd' wrong: found $nums, expected $expected"
7181
7182         expected=12
7183         cmd="$LFS find -size -5c -type f -lazy $dir"
7184         nums=$($cmd | wc -l)
7185         [ $nums -eq $expected ] ||
7186                 error "'$cmd' wrong: found $nums, expected $expected"
7187         cmd="$LFS find -size -5c -type f $dir"
7188         nums=$($cmd | wc -l)
7189         [ $nums -eq $expected ] ||
7190                 error "'$cmd' wrong: found $nums, expected $expected"
7191 }
7192 run_test 56r "check lfs find -size works"
7193
7194 test_56ra_sub() {
7195         local expected=$1
7196         local glimpses=$2
7197         local cmd="$3"
7198
7199         cancel_lru_locks $OSC
7200
7201         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7202         local nums=$($cmd | wc -l)
7203
7204         [ $nums -eq $expected ] ||
7205                 error "'$cmd' wrong: found $nums, expected $expected"
7206
7207         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7208
7209         if (( rpcs_before + glimpses != rpcs_after )); then
7210                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7211                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7212
7213                 if [[ $glimpses == 0 ]]; then
7214                         error "'$cmd' should not send glimpse RPCs to OST"
7215                 else
7216                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7217                 fi
7218         fi
7219 }
7220
7221 test_56ra() {
7222         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7223                 skip "MDS < 2.12.58 doesn't return LSOM data"
7224         local dir=$DIR/$tdir
7225         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7226
7227         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7228
7229         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7230         $LCTL set_param -n llite.*.statahead_agl=0
7231         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7232
7233         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7234         # open and close all files to ensure LSOM is updated
7235         cancel_lru_locks $OSC
7236         find $dir -type f | xargs cat > /dev/null
7237
7238         #   expect_found  glimpse_rpcs  command_to_run
7239         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7240         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7241         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7242         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7243
7244         echo "test" > $dir/$tfile
7245         echo "test2" > $dir/$tfile.2 && sync
7246         cancel_lru_locks $OSC
7247         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7248
7249         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7250         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7251         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7252         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7253
7254         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7255         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7256         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7257         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7258         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7259         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7260 }
7261 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7262
7263 test_56rb() {
7264         local dir=$DIR/$tdir
7265         local tmp=$TMP/$tfile.log
7266         local mdt_idx;
7267
7268         test_mkdir -p $dir || error "failed to mkdir $dir"
7269         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7270                 error "failed to setstripe $dir/$tfile"
7271         mdt_idx=$($LFS getdirstripe -i $dir)
7272         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7273
7274         stack_trap "rm -f $tmp" EXIT
7275         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7276         ! grep -q obd_uuid $tmp ||
7277                 error "failed to find --size +100K --ost 0 $dir"
7278         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7279         ! grep -q obd_uuid $tmp ||
7280                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7281 }
7282 run_test 56rb "check lfs find --size --ost/--mdt works"
7283
7284 test_56rc() {
7285         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7286         local dir=$DIR/$tdir
7287         local found
7288
7289         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7290         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7291         (( $MDSCOUNT > 2 )) &&
7292                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7293         mkdir $dir/$tdir-{1..10}
7294         touch $dir/$tfile-{1..10}
7295
7296         found=$($LFS find $dir --mdt-count 2 | wc -l)
7297         expect=11
7298         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7299
7300         found=$($LFS find $dir -T +1 | wc -l)
7301         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7302         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7303
7304         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7305         expect=11
7306         (( $found == $expect )) || error "found $found all_char, expect $expect"
7307
7308         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7309         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7310         (( $found == $expect )) || error "found $found all_char, expect $expect"
7311 }
7312 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7313
7314 test_56rd() {
7315         local dir=$DIR/$tdir
7316
7317         test_mkdir $dir
7318         rm -f $dir/*
7319
7320         mkfifo $dir/fifo || error "failed to create fifo file"
7321         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7322                 error "should not fail even cannot get projid from pipe file"
7323         found=$($LFS find $dir -t p --printf "%y")
7324         [[ "p" == $found ]] || error "found $found, expect p"
7325
7326         mknod $dir/chardev c 1 5 ||
7327                 error "failed to create character device file"
7328         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7329                 error "should not fail even cannot get projid from chardev file"
7330         found=$($LFS find $dir -t c --printf "%y")
7331         [[ "c" == $found ]] || error "found $found, expect c"
7332
7333         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7334         (( found == 2 )) || error "unable to list all files"
7335 }
7336 run_test 56rd "check lfs find --printf special files"
7337
7338 test_56s() { # LU-611 #LU-9369
7339         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7340
7341         local dir=$DIR/$tdir
7342         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7343
7344         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7345         for i in $(seq $NUMDIRS); do
7346                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7347         done
7348
7349         local expected=$NUMDIRS
7350         local cmd="$LFS find -c $OSTCOUNT $dir"
7351         local nums=$($cmd | wc -l)
7352
7353         [ $nums -eq $expected ] || {
7354                 $LFS getstripe -R $dir
7355                 error "'$cmd' wrong: found $nums, expected $expected"
7356         }
7357
7358         expected=$((NUMDIRS + onestripe))
7359         cmd="$LFS find -stripe-count +0 -type f $dir"
7360         nums=$($cmd | wc -l)
7361         [ $nums -eq $expected ] || {
7362                 $LFS getstripe -R $dir
7363                 error "'$cmd' wrong: found $nums, expected $expected"
7364         }
7365
7366         expected=$onestripe
7367         cmd="$LFS find -stripe-count 1 -type f $dir"
7368         nums=$($cmd | wc -l)
7369         [ $nums -eq $expected ] || {
7370                 $LFS getstripe -R $dir
7371                 error "'$cmd' wrong: found $nums, expected $expected"
7372         }
7373
7374         cmd="$LFS find -stripe-count -2 -type f $dir"
7375         nums=$($cmd | wc -l)
7376         [ $nums -eq $expected ] || {
7377                 $LFS getstripe -R $dir
7378                 error "'$cmd' wrong: found $nums, expected $expected"
7379         }
7380
7381         expected=0
7382         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7383         nums=$($cmd | wc -l)
7384         [ $nums -eq $expected ] || {
7385                 $LFS getstripe -R $dir
7386                 error "'$cmd' wrong: found $nums, expected $expected"
7387         }
7388 }
7389 run_test 56s "check lfs find -stripe-count works"
7390
7391 test_56t() { # LU-611 #LU-9369
7392         local dir=$DIR/$tdir
7393
7394         setup_56 $dir 0 $NUMDIRS
7395         for i in $(seq $NUMDIRS); do
7396                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7397         done
7398
7399         local expected=$NUMDIRS
7400         local cmd="$LFS find -S 8M $dir"
7401         local nums=$($cmd | wc -l)
7402
7403         [ $nums -eq $expected ] || {
7404                 $LFS getstripe -R $dir
7405                 error "'$cmd' wrong: found $nums, expected $expected"
7406         }
7407         rm -rf $dir
7408
7409         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7410
7411         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7412
7413         expected=$(((NUMDIRS + 1) * NUMFILES))
7414         cmd="$LFS find -stripe-size 512k -type f $dir"
7415         nums=$($cmd | wc -l)
7416         [ $nums -eq $expected ] ||
7417                 error "'$cmd' wrong: found $nums, expected $expected"
7418
7419         cmd="$LFS find -stripe-size +320k -type f $dir"
7420         nums=$($cmd | wc -l)
7421         [ $nums -eq $expected ] ||
7422                 error "'$cmd' wrong: found $nums, expected $expected"
7423
7424         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7425         cmd="$LFS find -stripe-size +200k -type f $dir"
7426         nums=$($cmd | wc -l)
7427         [ $nums -eq $expected ] ||
7428                 error "'$cmd' wrong: found $nums, expected $expected"
7429
7430         cmd="$LFS find -stripe-size -640k -type f $dir"
7431         nums=$($cmd | wc -l)
7432         [ $nums -eq $expected ] ||
7433                 error "'$cmd' wrong: found $nums, expected $expected"
7434
7435         expected=4
7436         cmd="$LFS find -stripe-size 256k -type f $dir"
7437         nums=$($cmd | wc -l)
7438         [ $nums -eq $expected ] ||
7439                 error "'$cmd' wrong: found $nums, expected $expected"
7440
7441         cmd="$LFS find -stripe-size -320k -type f $dir"
7442         nums=$($cmd | wc -l)
7443         [ $nums -eq $expected ] ||
7444                 error "'$cmd' wrong: found $nums, expected $expected"
7445
7446         expected=0
7447         cmd="$LFS find -stripe-size 1024k -type f $dir"
7448         nums=$($cmd | wc -l)
7449         [ $nums -eq $expected ] ||
7450                 error "'$cmd' wrong: found $nums, expected $expected"
7451 }
7452 run_test 56t "check lfs find -stripe-size works"
7453
7454 test_56u() { # LU-611
7455         local dir=$DIR/$tdir
7456
7457         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7458
7459         if [[ $OSTCOUNT -gt 1 ]]; then
7460                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7461                 onestripe=4
7462         else
7463                 onestripe=0
7464         fi
7465
7466         local expected=$(((NUMDIRS + 1) * NUMFILES))
7467         local cmd="$LFS find -stripe-index 0 -type f $dir"
7468         local nums=$($cmd | wc -l)
7469
7470         [ $nums -eq $expected ] ||
7471                 error "'$cmd' wrong: found $nums, expected $expected"
7472
7473         expected=$onestripe
7474         cmd="$LFS find -stripe-index 1 -type f $dir"
7475         nums=$($cmd | wc -l)
7476         [ $nums -eq $expected ] ||
7477                 error "'$cmd' wrong: found $nums, expected $expected"
7478
7479         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7480         nums=$($cmd | wc -l)
7481         [ $nums -eq $expected ] ||
7482                 error "'$cmd' wrong: found $nums, expected $expected"
7483
7484         expected=0
7485         # This should produce an error and not return any files
7486         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7487         nums=$($cmd 2>/dev/null | wc -l)
7488         [ $nums -eq $expected ] ||
7489                 error "'$cmd' wrong: found $nums, expected $expected"
7490
7491         if [[ $OSTCOUNT -gt 1 ]]; then
7492                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7493                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7494                 nums=$($cmd | wc -l)
7495                 [ $nums -eq $expected ] ||
7496                         error "'$cmd' wrong: found $nums, expected $expected"
7497         fi
7498 }
7499 run_test 56u "check lfs find -stripe-index works"
7500
7501 test_56v() {
7502         local mdt_idx=0
7503         local dir=$DIR/$tdir
7504
7505         setup_56 $dir $NUMFILES $NUMDIRS
7506
7507         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7508         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7509
7510         for file in $($LFS find -m $UUID $dir); do
7511                 file_midx=$($LFS getstripe -m $file)
7512                 [ $file_midx -eq $mdt_idx ] ||
7513                         error "lfs find -m $UUID != getstripe -m $file_midx"
7514         done
7515 }
7516 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7517
7518 test_56wa() {
7519         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7521
7522         local dir=$DIR/$tdir
7523
7524         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7525         stack_trap "rm -rf $dir"
7526
7527         local stripe_size=$($LFS getstripe -S -d $dir) ||
7528                 error "$LFS getstripe -S -d $dir failed"
7529         stripe_size=${stripe_size%% *}
7530
7531         local file_size=$((stripe_size * OSTCOUNT))
7532         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7533         local required_space=$((file_num * file_size))
7534         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7535                            head -n1)
7536         (( free_space >= required_space / 1024 )) ||
7537                 skip_env "need $required_space, have $free_space kbytes"
7538
7539         local dd_bs=65536
7540         local dd_count=$((file_size / dd_bs))
7541
7542         # write data into the files
7543         local i
7544         local j
7545         local file
7546
7547         for ((i = 1; i <= NUMFILES; i++ )); do
7548                 file=$dir/file$i
7549                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7550                         error "write data into $file failed"
7551         done
7552         for ((i = 1; i <= NUMDIRS; i++ )); do
7553                 for ((j = 1; j <= NUMFILES; j++ )); do
7554                         file=$dir/dir$i/file$j
7555                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7556                                 error "write data into $file failed"
7557                 done
7558         done
7559
7560         # $LFS_MIGRATE will fail if hard link migration is unsupported
7561         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7562                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7563                         error "creating links to $dir/dir1/file1 failed"
7564         fi
7565
7566         local expected=-1
7567
7568         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7569
7570         # lfs_migrate file
7571         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7572
7573         echo "$cmd"
7574         eval $cmd || error "$cmd failed"
7575
7576         check_stripe_count $dir/file1 $expected
7577
7578         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7579                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7580                 # OST 1 if it is on OST 0. This file is small enough to
7581                 # be on only one stripe.
7582                 file=$dir/migr_1_ost
7583                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7584                         error "write data into $file failed"
7585                 local obdidx=$($LFS getstripe -i $file)
7586                 local oldmd5=$(md5sum $file)
7587                 local newobdidx=0
7588
7589                 (( obdidx != 0 )) || newobdidx=1
7590                 cmd="$LFS migrate -i $newobdidx $file"
7591                 echo $cmd
7592                 eval $cmd || error "$cmd failed"
7593
7594                 local realobdix=$($LFS getstripe -i $file)
7595                 local newmd5=$(md5sum $file)
7596
7597                 (( $newobdidx == $realobdix )) ||
7598                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7599                 [[ "$oldmd5" == "$newmd5" ]] ||
7600                         error "md5sum differ: $oldmd5, $newmd5"
7601         fi
7602
7603         # lfs_migrate dir
7604         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7605         echo "$cmd"
7606         eval $cmd || error "$cmd failed"
7607
7608         for (( j = 1; j <= NUMFILES; j++ )); do
7609                 check_stripe_count $dir/dir1/file$j $expected
7610         done
7611
7612         # lfs_migrate works with lfs find
7613         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7614              $LFS_MIGRATE -y -c $expected"
7615         echo "$cmd"
7616         eval $cmd || error "$cmd failed"
7617
7618         for (( i = 2; i <= NUMFILES; i++ )); do
7619                 check_stripe_count $dir/file$i $expected
7620         done
7621         for (( i = 2; i <= NUMDIRS; i++ )); do
7622                 for (( j = 1; j <= NUMFILES; j++ )); do
7623                         check_stripe_count $dir/dir$i/file$j $expected
7624                 done
7625         done
7626 }
7627 run_test 56wa "check lfs_migrate -c stripe_count works"
7628
7629 test_56wb() {
7630         local file1=$DIR/$tdir/file1
7631         local create_pool=false
7632         local initial_pool=$($LFS getstripe -p $DIR)
7633         local pool_list=()
7634         local pool=""
7635
7636         echo -n "Creating test dir..."
7637         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7638         echo "done."
7639
7640         echo -n "Creating test file..."
7641         touch $file1 || error "cannot create file"
7642         echo "done."
7643
7644         echo -n "Detecting existing pools..."
7645         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7646
7647         if [ ${#pool_list[@]} -gt 0 ]; then
7648                 echo "${pool_list[@]}"
7649                 for thispool in "${pool_list[@]}"; do
7650                         if [[ -z "$initial_pool" ||
7651                               "$initial_pool" != "$thispool" ]]; then
7652                                 pool="$thispool"
7653                                 echo "Using existing pool '$pool'"
7654                                 break
7655                         fi
7656                 done
7657         else
7658                 echo "none detected."
7659         fi
7660         if [ -z "$pool" ]; then
7661                 pool=${POOL:-testpool}
7662                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7663                 echo -n "Creating pool '$pool'..."
7664                 create_pool=true
7665                 pool_add $pool &> /dev/null ||
7666                         error "pool_add failed"
7667                 echo "done."
7668
7669                 echo -n "Adding target to pool..."
7670                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7671                         error "pool_add_targets failed"
7672                 echo "done."
7673         fi
7674
7675         echo -n "Setting pool using -p option..."
7676         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7677                 error "migrate failed rc = $?"
7678         echo "done."
7679
7680         echo -n "Verifying test file is in pool after migrating..."
7681         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7682                 error "file was not migrated to pool $pool"
7683         echo "done."
7684
7685         echo -n "Removing test file from pool '$pool'..."
7686         # "lfs migrate $file" won't remove the file from the pool
7687         # until some striping information is changed.
7688         $LFS migrate -c 1 $file1 &> /dev/null ||
7689                 error "cannot remove from pool"
7690         [ "$($LFS getstripe -p $file1)" ] &&
7691                 error "pool still set"
7692         echo "done."
7693
7694         echo -n "Setting pool using --pool option..."
7695         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7696                 error "migrate failed rc = $?"
7697         echo "done."
7698
7699         # Clean up
7700         rm -f $file1
7701         if $create_pool; then
7702                 destroy_test_pools 2> /dev/null ||
7703                         error "destroy test pools failed"
7704         fi
7705 }
7706 run_test 56wb "check lfs_migrate pool support"
7707
7708 test_56wc() {
7709         local file1="$DIR/$tdir/$tfile"
7710         local md5
7711         local parent_ssize
7712         local parent_scount
7713         local cur_ssize
7714         local cur_scount
7715         local orig_ssize
7716         local new_scount
7717         local cur_comp
7718
7719         echo -n "Creating test dir..."
7720         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7721         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7722                 error "cannot set stripe by '-S 1M -c 1'"
7723         echo "done"
7724
7725         echo -n "Setting initial stripe for test file..."
7726         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7727                 error "cannot set stripe"
7728         cur_ssize=$($LFS getstripe -S "$file1")
7729         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7730         echo "done."
7731
7732         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7733         stack_trap "rm -f $file1"
7734         md5="$(md5sum $file1)"
7735
7736         # File currently set to -S 512K -c 1
7737
7738         # Ensure -c and -S options are rejected when -R is set
7739         echo -n "Verifying incompatible options are detected..."
7740         $LFS_MIGRATE -R -c 1 "$file1" &&
7741                 error "incompatible -R and -c options not detected"
7742         $LFS_MIGRATE -R -S 1M "$file1" &&
7743                 error "incompatible -R and -S options not detected"
7744         $LFS_MIGRATE -R -p pool "$file1" &&
7745                 error "incompatible -R and -p options not detected"
7746         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7747                 error "incompatible -R and -E options not detected"
7748         $LFS_MIGRATE -R -A "$file1" &&
7749                 error "incompatible -R and -A options not detected"
7750         $LFS_MIGRATE -A -c 1 "$file1" &&
7751                 error "incompatible -A and -c options not detected"
7752         $LFS_MIGRATE -A -S 1M "$file1" &&
7753                 error "incompatible -A and -S options not detected"
7754         $LFS_MIGRATE -A -p pool "$file1" &&
7755                 error "incompatible -A and -p options not detected"
7756         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7757                 error "incompatible -A and -E options not detected"
7758         echo "done."
7759
7760         # Ensure unrecognized options are passed through to 'lfs migrate'
7761         echo -n "Verifying -S option is passed through to lfs migrate..."
7762         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7763         cur_ssize=$($LFS getstripe -S "$file1")
7764         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7765         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7766         echo "done."
7767
7768         # File currently set to -S 1M -c 1
7769
7770         # Ensure long options are supported
7771         echo -n "Verifying long options supported..."
7772         $LFS_MIGRATE --non-block "$file1" ||
7773                 error "long option without argument not supported"
7774         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7775                 error "long option with argument not supported"
7776         cur_ssize=$($LFS getstripe -S "$file1")
7777         (( cur_ssize == 524288 )) ||
7778                 error "migrate --stripe-size $cur_ssize != 524288"
7779         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7780         echo "done."
7781
7782         # File currently set to -S 512K -c 1
7783
7784         if (( OSTCOUNT > 1 )); then
7785                 echo -n "Verifying explicit stripe count can be set..."
7786                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7787                 cur_scount=$($LFS getstripe -c "$file1")
7788                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7789                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7790                         error "file data has changed (3)"
7791                 echo "done."
7792         fi
7793
7794         # File currently set to -S 512K -c 1 or -S 512K -c 2
7795
7796         # Ensure parent striping is used if -R is set, and no stripe
7797         # count or size is specified
7798         echo -n "Setting stripe for parent directory..."
7799         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7800                 error "cannot set stripe '-S 2M -c 1'"
7801         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7802         echo "done."
7803
7804         echo -n "Verifying restripe option uses parent stripe settings..."
7805         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7806         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7807         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7808         cur_ssize=$($LFS getstripe -S "$file1")
7809         (( cur_ssize == parent_ssize )) ||
7810                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7811         cur_scount=$($LFS getstripe -c "$file1")
7812         (( cur_scount == parent_scount )) ||
7813                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7814         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7815         echo "done."
7816
7817         # File currently set to -S 1M -c 1
7818
7819         # Ensure striping is preserved if -R is not set, and no stripe
7820         # count or size is specified
7821         echo -n "Verifying striping size preserved when not specified..."
7822         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7823         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7824                 error "cannot set stripe on parent directory"
7825         $LFS_MIGRATE "$file1" || error "migrate failed"
7826         cur_ssize=$($LFS getstripe -S "$file1")
7827         (( cur_ssize == orig_ssize )) ||
7828                 error "migrate by default $cur_ssize != $orig_ssize"
7829         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7830         echo "done."
7831
7832         # Ensure file name properly detected when final option has no argument
7833         echo -n "Verifying file name properly detected..."
7834         $LFS_MIGRATE "$file1" ||
7835                 error "file name interpreted as option argument"
7836         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7837         echo "done."
7838
7839         # Ensure PFL arguments are passed through properly
7840         echo -n "Verifying PFL options passed through..."
7841         new_scount=$(((OSTCOUNT + 1) / 2))
7842         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7843                 error "migrate PFL arguments failed"
7844         cur_comp=$($LFS getstripe --comp-count $file1)
7845         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7846         cur_scount=$($LFS getstripe --stripe-count $file1)
7847         (( cur_scount == new_scount)) ||
7848                 error "PFL stripe count $cur_scount != $new_scount"
7849         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7850         echo "done."
7851 }
7852 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7853
7854 test_56wd() {
7855         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7856
7857         local file1=$DIR/$tdir/$tfile
7858
7859         echo -n "Creating test dir..."
7860         test_mkdir $DIR/$tdir || error "cannot create dir"
7861         echo "done."
7862
7863         echo -n "Creating test file..."
7864         echo "$tfile" > $file1
7865         echo "done."
7866
7867         # Ensure 'lfs migrate' will fail by using a non-existent option,
7868         # and make sure rsync is not called to recover
7869         echo -n "Make sure --no-rsync option works..."
7870         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7871                 grep -q 'refusing to fall back to rsync' ||
7872                 error "rsync was called with --no-rsync set"
7873         echo "done."
7874
7875         # Ensure rsync is called without trying 'lfs migrate' first
7876         echo -n "Make sure --rsync option works..."
7877         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7878                 grep -q 'falling back to rsync' &&
7879                 error "lfs migrate was called with --rsync set"
7880         echo "done."
7881 }
7882 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7883
7884 test_56we() {
7885         local td=$DIR/$tdir
7886         local tf=$td/$tfile
7887
7888         test_mkdir $td || error "cannot create $td"
7889         touch $tf || error "cannot touch $tf"
7890
7891         echo -n "Make sure --non-direct|-D works..."
7892         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7893                 grep -q "lfs migrate --non-direct" ||
7894                 error "--non-direct option cannot work correctly"
7895         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7896                 grep -q "lfs migrate -D" ||
7897                 error "-D option cannot work correctly"
7898         echo "done."
7899 }
7900 run_test 56we "check lfs_migrate --non-direct|-D support"
7901
7902 test_56x() {
7903         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7904         check_swap_layouts_support
7905
7906         local dir=$DIR/$tdir
7907         local ref1=/etc/passwd
7908         local file1=$dir/file1
7909
7910         test_mkdir $dir || error "creating dir $dir"
7911         $LFS setstripe -c 2 $file1
7912         cp $ref1 $file1
7913         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7914         stripe=$($LFS getstripe -c $file1)
7915         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7916         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7917
7918         # clean up
7919         rm -f $file1
7920 }
7921 run_test 56x "lfs migration support"
7922
7923 test_56xa() {
7924         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7925         check_swap_layouts_support
7926
7927         local dir=$DIR/$tdir/$testnum
7928
7929         test_mkdir -p $dir
7930
7931         local ref1=/etc/passwd
7932         local file1=$dir/file1
7933
7934         $LFS setstripe -c 2 $file1
7935         cp $ref1 $file1
7936         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7937
7938         local stripe=$($LFS getstripe -c $file1)
7939
7940         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7941         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7942
7943         # clean up
7944         rm -f $file1
7945 }
7946 run_test 56xa "lfs migration --block support"
7947
7948 check_migrate_links() {
7949         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7950         local dir="$1"
7951         local file1="$dir/file1"
7952         local begin="$2"
7953         local count="$3"
7954         local runas="$4"
7955         local total_count=$(($begin + $count - 1))
7956         local symlink_count=10
7957         local uniq_count=10
7958
7959         if [ ! -f "$file1" ]; then
7960                 echo -n "creating initial file..."
7961                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7962                         error "cannot setstripe initial file"
7963                 echo "done"
7964
7965                 echo -n "creating symlinks..."
7966                 for s in $(seq 1 $symlink_count); do
7967                         ln -s "$file1" "$dir/slink$s" ||
7968                                 error "cannot create symlinks"
7969                 done
7970                 echo "done"
7971
7972                 echo -n "creating nonlinked files..."
7973                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7974                         error "cannot create nonlinked files"
7975                 echo "done"
7976         fi
7977
7978         # create hard links
7979         if [ ! -f "$dir/file$total_count" ]; then
7980                 echo -n "creating hard links $begin:$total_count..."
7981                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7982                         /dev/null || error "cannot create hard links"
7983                 echo "done"
7984         fi
7985
7986         echo -n "checking number of hard links listed in xattrs..."
7987         local fid=$($LFS getstripe -F "$file1")
7988         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7989
7990         echo "${#paths[*]}"
7991         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7992                         skip "hard link list has unexpected size, skipping test"
7993         fi
7994         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7995                         error "link names should exceed xattrs size"
7996         fi
7997
7998         echo -n "migrating files..."
7999         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8000         local rc=$?
8001         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8002         echo "done"
8003
8004         # make sure all links have been properly migrated
8005         echo -n "verifying files..."
8006         fid=$($LFS getstripe -F "$file1") ||
8007                 error "cannot get fid for file $file1"
8008         for i in $(seq 2 $total_count); do
8009                 local fid2=$($LFS getstripe -F $dir/file$i)
8010
8011                 [ "$fid2" == "$fid" ] ||
8012                         error "migrated hard link has mismatched FID"
8013         done
8014
8015         # make sure hard links were properly detected, and migration was
8016         # performed only once for the entire link set; nonlinked files should
8017         # also be migrated
8018         local actual=$(grep -c 'done' <<< "$migrate_out")
8019         local expected=$(($uniq_count + 1))
8020
8021         [ "$actual" -eq  "$expected" ] ||
8022                 error "hard links individually migrated ($actual != $expected)"
8023
8024         # make sure the correct number of hard links are present
8025         local hardlinks=$(stat -c '%h' "$file1")
8026
8027         [ $hardlinks -eq $total_count ] ||
8028                 error "num hard links $hardlinks != $total_count"
8029         echo "done"
8030
8031         return 0
8032 }
8033
8034 test_56xb() {
8035         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8036                 skip "Need MDS version at least 2.10.55"
8037
8038         local dir="$DIR/$tdir"
8039
8040         test_mkdir "$dir" || error "cannot create dir $dir"
8041
8042         echo "testing lfs migrate mode when all links fit within xattrs"
8043         check_migrate_links "$dir" 2 99
8044
8045         echo "testing rsync mode when all links fit within xattrs"
8046         check_migrate_links --rsync "$dir" 2 99
8047
8048         echo "testing lfs migrate mode when all links do not fit within xattrs"
8049         check_migrate_links "$dir" 101 100
8050
8051         echo "testing rsync mode when all links do not fit within xattrs"
8052         check_migrate_links --rsync "$dir" 101 100
8053
8054         chown -R $RUNAS_ID $dir
8055         echo "testing non-root lfs migrate mode when not all links are in xattr"
8056         check_migrate_links "$dir" 101 100 "$RUNAS"
8057
8058         # clean up
8059         rm -rf $dir
8060 }
8061 run_test 56xb "lfs migration hard link support"
8062
8063 test_56xc() {
8064         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8065
8066         local dir="$DIR/$tdir"
8067
8068         test_mkdir "$dir" || error "cannot create dir $dir"
8069
8070         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8071         echo -n "Setting initial stripe for 20MB test file..."
8072         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8073                 error "cannot setstripe 20MB file"
8074         echo "done"
8075         echo -n "Sizing 20MB test file..."
8076         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8077         echo "done"
8078         echo -n "Verifying small file autostripe count is 1..."
8079         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8080                 error "cannot migrate 20MB file"
8081         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8082                 error "cannot get stripe for $dir/20mb"
8083         [ $stripe_count -eq 1 ] ||
8084                 error "unexpected stripe count $stripe_count for 20MB file"
8085         rm -f "$dir/20mb"
8086         echo "done"
8087
8088         # Test 2: File is small enough to fit within the available space on
8089         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8090         # have at least an additional 1KB for each desired stripe for test 3
8091         echo -n "Setting stripe for 1GB test file..."
8092         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8093         echo "done"
8094         echo -n "Sizing 1GB test file..."
8095         # File size is 1GB + 3KB
8096         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8097         echo "done"
8098
8099         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8100         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8101         if (( avail > 524288 * OSTCOUNT )); then
8102                 echo -n "Migrating 1GB file..."
8103                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8104                         error "cannot migrate 1GB file"
8105                 echo "done"
8106                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8107                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8108                         error "cannot getstripe for 1GB file"
8109                 [ $stripe_count -eq 2 ] ||
8110                         error "unexpected stripe count $stripe_count != 2"
8111                 echo "done"
8112         fi
8113
8114         # Test 3: File is too large to fit within the available space on
8115         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8116         if [ $OSTCOUNT -ge 3 ]; then
8117                 # The required available space is calculated as
8118                 # file size (1GB + 3KB) / OST count (3).
8119                 local kb_per_ost=349526
8120
8121                 echo -n "Migrating 1GB file with limit..."
8122                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8123                         error "cannot migrate 1GB file with limit"
8124                 echo "done"
8125
8126                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8127                 echo -n "Verifying 1GB autostripe count with limited space..."
8128                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8129                         error "unexpected stripe count $stripe_count (min 3)"
8130                 echo "done"
8131         fi
8132
8133         # clean up
8134         rm -rf $dir
8135 }
8136 run_test 56xc "lfs migration autostripe"
8137
8138 test_56xd() {
8139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8140
8141         local dir=$DIR/$tdir
8142         local f_mgrt=$dir/$tfile.mgrt
8143         local f_yaml=$dir/$tfile.yaml
8144         local f_copy=$dir/$tfile.copy
8145         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8146         local layout_copy="-c 2 -S 2M -i 1"
8147         local yamlfile=$dir/yamlfile
8148         local layout_before;
8149         local layout_after;
8150
8151         test_mkdir "$dir" || error "cannot create dir $dir"
8152         stack_trap "rm -rf $dir"
8153         $LFS setstripe $layout_yaml $f_yaml ||
8154                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8155         $LFS getstripe --yaml $f_yaml > $yamlfile
8156         $LFS setstripe $layout_copy $f_copy ||
8157                 error "cannot setstripe $f_copy with layout $layout_copy"
8158         touch $f_mgrt
8159         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8160
8161         # 1. test option --yaml
8162         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8163                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8164         layout_before=$(get_layout_param $f_yaml)
8165         layout_after=$(get_layout_param $f_mgrt)
8166         [ "$layout_after" == "$layout_before" ] ||
8167                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8168
8169         # 2. test option --copy
8170         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8171                 error "cannot migrate $f_mgrt with --copy $f_copy"
8172         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8173         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8174         [ "$layout_after" == "$layout_before" ] ||
8175                 error "lfs_migrate --copy: $layout_after != $layout_before"
8176 }
8177 run_test 56xd "check lfs_migrate --yaml and --copy support"
8178
8179 test_56xe() {
8180         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8181
8182         local dir=$DIR/$tdir
8183         local f_comp=$dir/$tfile
8184         local layout="-E 1M -S 512K -E 2M -c 2 -E 3M -c 2 -E eof -c $OSTCOUNT"
8185         local layout_before=""
8186         local layout_after=""
8187
8188         test_mkdir "$dir" || error "cannot create dir $dir"
8189         stack_trap "rm -rf $dir"
8190         $LFS setstripe $layout $f_comp ||
8191                 error "cannot setstripe $f_comp with layout $layout"
8192         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8193         dd if=/dev/zero of=$f_comp bs=1M count=4
8194
8195         # 1. migrate a comp layout file by lfs_migrate
8196         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8197         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8198         idx_before=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8199                      tr '\n' ' ')
8200         [ "$layout_before" == "$layout_after" ] ||
8201                 error "lfs_migrate: $layout_before != $layout_after"
8202
8203         # 2. migrate a comp layout file by lfs migrate
8204         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8205         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8206         idx_after=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8207                      tr '\n' ' ')
8208         [ "$layout_before" == "$layout_after" ] ||
8209                 error "lfs migrate: $layout_before != $layout_after"
8210
8211         # this may not fail every time with a broken lfs migrate, but will fail
8212         # often enough to notice, and will not have false positives very often
8213         [ "$idx_before" != "$idx_after" ] ||
8214                 error "lfs migrate: $idx_before == $idx_after"
8215 }
8216 run_test 56xe "migrate a composite layout file"
8217
8218 test_56xf() {
8219         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8220
8221         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8222                 skip "Need server version at least 2.13.53"
8223
8224         local dir=$DIR/$tdir
8225         local f_comp=$dir/$tfile
8226         local layout="-E 1M -c1 -E -1 -c2"
8227         local fid_before=""
8228         local fid_after=""
8229
8230         test_mkdir "$dir" || error "cannot create dir $dir"
8231         stack_trap "rm -rf $dir"
8232         $LFS setstripe $layout $f_comp ||
8233                 error "cannot setstripe $f_comp with layout $layout"
8234         fid_before=$($LFS getstripe --fid $f_comp)
8235         dd if=/dev/zero of=$f_comp bs=1M count=4
8236
8237         # 1. migrate a comp layout file to a comp layout
8238         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8239         fid_after=$($LFS getstripe --fid $f_comp)
8240         [ "$fid_before" == "$fid_after" ] ||
8241                 error "comp-to-comp migrate: $fid_before != $fid_after"
8242
8243         # 2. migrate a comp layout file to a plain layout
8244         $LFS migrate -c2 $f_comp ||
8245                 error "cannot migrate $f_comp by lfs migrate"
8246         fid_after=$($LFS getstripe --fid $f_comp)
8247         [ "$fid_before" == "$fid_after" ] ||
8248                 error "comp-to-plain migrate: $fid_before != $fid_after"
8249
8250         # 3. migrate a plain layout file to a comp layout
8251         $LFS migrate $layout $f_comp ||
8252                 error "cannot migrate $f_comp by lfs migrate"
8253         fid_after=$($LFS getstripe --fid $f_comp)
8254         [ "$fid_before" == "$fid_after" ] ||
8255                 error "plain-to-comp migrate: $fid_before != $fid_after"
8256 }
8257 run_test 56xf "FID is not lost during migration of a composite layout file"
8258
8259 check_file_ost_range() {
8260         local file="$1"
8261         shift
8262         local range="$*"
8263         local -a file_range
8264         local idx
8265
8266         file_range=($($LFS getstripe -y "$file" |
8267                 awk '/l_ost_idx:/ { print $NF }'))
8268
8269         if [[ "${#file_range[@]}" = 0 ]]; then
8270                 echo "No osts found for $file"
8271                 return 1
8272         fi
8273
8274         for idx in "${file_range[@]}"; do
8275                 [[ " $range " =~ " $idx " ]] ||
8276                         return 1
8277         done
8278
8279         return 0
8280 }
8281
8282 sub_test_56xg() {
8283         local stripe_opt="$1"
8284         local pool="$2"
8285         shift 2
8286         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8287
8288         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8289                 error "Fail to migrate $tfile on $pool"
8290         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8291                 error "$tfile is not in pool $pool"
8292         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8293                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8294 }
8295
8296 test_56xg() {
8297         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8298         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8299         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8300                 skip "Need MDS version newer than 2.14.52"
8301
8302         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8303         local -a pool_ranges=("0 0" "1 1" "0 1")
8304
8305         # init pools
8306         for i in "${!pool_names[@]}"; do
8307                 pool_add ${pool_names[$i]} ||
8308                         error "pool_add failed (pool: ${pool_names[$i]})"
8309                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8310                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8311         done
8312
8313         # init the file to migrate
8314         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8315                 error "Unable to create $tfile on OST1"
8316         stack_trap "rm -f $DIR/$tfile"
8317         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8318                 error "Unable to write on $tfile"
8319
8320         echo "1. migrate $tfile on pool ${pool_names[0]}"
8321         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8322
8323         echo "2. migrate $tfile on pool ${pool_names[2]}"
8324         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8325
8326         echo "3. migrate $tfile on pool ${pool_names[1]}"
8327         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8328
8329         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8330         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8331         echo
8332
8333         # Clean pools
8334         destroy_test_pools ||
8335                 error "pool_destroy failed"
8336 }
8337 run_test 56xg "lfs migrate pool support"
8338
8339 test_56xh() {
8340         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8341
8342         local size_mb=25
8343         local file1=$DIR/$tfile
8344         local tmp1=$TMP/$tfile.tmp
8345
8346         $LFS setstripe -c 2 $file1
8347
8348         stack_trap "rm -f $file1 $tmp1"
8349         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8350                         error "error creating $tmp1"
8351         ls -lsh $tmp1
8352         cp $tmp1 $file1
8353
8354         local start=$SECONDS
8355
8356         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8357                 error "migrate failed rc = $?"
8358
8359         local elapsed=$((SECONDS - start))
8360
8361         # with 1MB/s, elapsed should equal size_mb
8362         (( elapsed >= size_mb * 95 / 100 )) ||
8363                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8364
8365         (( elapsed <= size_mb * 120 / 100 )) ||
8366                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8367
8368         (( elapsed <= size_mb * 350 / 100 )) ||
8369                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8370
8371         stripe=$($LFS getstripe -c $file1)
8372         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8373         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8374
8375         # Clean up file (since it is multiple MB)
8376         rm -f $file1 $tmp1
8377 }
8378 run_test 56xh "lfs migrate bandwidth limitation support"
8379
8380 test_56xi() {
8381         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8382         verify_yaml_available || skip_env "YAML verification not installed"
8383
8384         local size_mb=5
8385         local file1=$DIR/$tfile.1
8386         local file2=$DIR/$tfile.2
8387         local file3=$DIR/$tfile.3
8388         local output_file=$DIR/$tfile.out
8389         local tmp1=$TMP/$tfile.tmp
8390
8391         $LFS setstripe -c 2 $file1
8392         $LFS setstripe -c 2 $file2
8393         $LFS setstripe -c 2 $file3
8394
8395         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8396         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8397                         error "error creating $tmp1"
8398         ls -lsh $tmp1
8399         cp $tmp1 $file1
8400         cp $tmp1 $file2
8401         cp $tmp1 $file3
8402
8403         $LFS migrate --stats --stats-interval=1 \
8404                 -c 1 $file1 $file2 $file3 1> $output_file ||
8405                 error "migrate failed rc = $?"
8406
8407         cat $output_file
8408         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8409
8410         # Clean up file (since it is multiple MB)
8411         rm -f $file1 $file2 $file3 $tmp1 $output_file
8412 }
8413 run_test 56xi "lfs migrate stats support"
8414
8415 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8416         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8417
8418         local file=$DIR/$tfile
8419         local linkdir=$DIR/$tdir
8420
8421         test_mkdir $linkdir || error "fail to create $linkdir"
8422         $LFS setstripe -i 0 -c 1 -S1M $file
8423         stack_trap "rm -rf $file $linkdir"
8424         dd if=/dev/urandom of=$file bs=1M count=10 ||
8425                 error "fail to create $file"
8426
8427         # Create file links
8428         local cpts
8429         local threads_max
8430         local nlinks
8431
8432         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8433         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8434         (( nlinks = thread_max * 3 / 2 / cpts))
8435
8436         echo "create $nlinks hard links of $file"
8437         createmany -l $file $linkdir/link $nlinks
8438
8439         # Parallel migrates (should not block)
8440         local i
8441         for ((i = 0; i < nlinks; i++)); do
8442                 echo $linkdir/link$i
8443         done | xargs -n1 -P $nlinks $LFS migrate -c2
8444
8445         local stripe_count
8446         stripe_count=$($LFS getstripe -c $file) ||
8447                 error "fail to get stripe count on $file"
8448
8449         ((stripe_count == 2)) ||
8450                 error "fail to migrate $file (stripe_count = $stripe_count)"
8451 }
8452 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8453
8454 test_56xk() {
8455         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8456
8457         local size_mb=5
8458         local file1=$DIR/$tfile
8459
8460         stack_trap "rm -f $file1"
8461         $LFS setstripe -c 1 $file1
8462         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8463                 error "error creating $file1"
8464         $LFS mirror extend -N $file1 || error "can't mirror"
8465         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8466                 error "can't dd"
8467         $LFS getstripe $file1 | grep stale ||
8468                 error "one component must be stale"
8469
8470         local start=$SECONDS
8471         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8472                 error "migrate failed rc = $?"
8473         local elapsed=$((SECONDS - start))
8474         $LFS getstripe $file1 | grep stale &&
8475                 error "all components must be sync"
8476
8477         # with 1MB/s, elapsed should equal size_mb
8478         (( elapsed >= size_mb * 95 / 100 )) ||
8479                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8480
8481         (( elapsed <= size_mb * 120 / 100 )) ||
8482                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8483
8484         (( elapsed <= size_mb * 350 / 100 )) ||
8485                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8486 }
8487 run_test 56xk "lfs mirror resync bandwidth limitation support"
8488
8489 test_56xl() {
8490         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8491         verify_yaml_available || skip_env "YAML verification not installed"
8492
8493         local size_mb=5
8494         local file1=$DIR/$tfile.1
8495         local output_file=$DIR/$tfile.out
8496
8497         stack_trap "rm -f $file1"
8498         $LFS setstripe -c 1 $file1
8499         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8500                 error "error creating $file1"
8501         $LFS mirror extend -N $file1 || error "can't mirror"
8502         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8503                 error "can't dd"
8504         $LFS getstripe $file1 | grep stale ||
8505                 error "one component must be stale"
8506         $LFS getstripe $file1
8507
8508         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8509                 error "resync failed rc = $?"
8510         $LFS getstripe $file1 | grep stale &&
8511                 error "all components must be sync"
8512
8513         cat $output_file
8514         cat $output_file | verify_yaml || error "stats is not valid YAML"
8515 }
8516 run_test 56xl "lfs mirror resync stats support"
8517
8518 test_56y() {
8519         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8520                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8521
8522         local res=""
8523         local dir=$DIR/$tdir
8524         local f1=$dir/file1
8525         local f2=$dir/file2
8526
8527         test_mkdir -p $dir || error "creating dir $dir"
8528         touch $f1 || error "creating std file $f1"
8529         $MULTIOP $f2 H2c || error "creating released file $f2"
8530
8531         # a directory can be raid0, so ask only for files
8532         res=$($LFS find $dir -L raid0 -type f | wc -l)
8533         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8534
8535         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8536         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8537
8538         # only files can be released, so no need to force file search
8539         res=$($LFS find $dir -L released)
8540         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8541
8542         res=$($LFS find $dir -type f \! -L released)
8543         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8544 }
8545 run_test 56y "lfs find -L raid0|released"
8546
8547 test_56z() { # LU-4824
8548         # This checks to make sure 'lfs find' continues after errors
8549         # There are two classes of errors that should be caught:
8550         # - If multiple paths are provided, all should be searched even if one
8551         #   errors out
8552         # - If errors are encountered during the search, it should not terminate
8553         #   early
8554         local dir=$DIR/$tdir
8555         local i
8556
8557         test_mkdir $dir
8558         for i in d{0..9}; do
8559                 test_mkdir $dir/$i
8560                 touch $dir/$i/$tfile
8561         done
8562         $LFS find $DIR/non_existent_dir $dir &&
8563                 error "$LFS find did not return an error"
8564         # Make a directory unsearchable. This should NOT be the last entry in
8565         # directory order.  Arbitrarily pick the 6th entry
8566         chmod 700 $($LFS find $dir -type d | sed '6!d')
8567
8568         $RUNAS $LFS find $DIR/non_existent $dir
8569         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8570
8571         # The user should be able to see 10 directories and 9 files
8572         (( count == 19 )) ||
8573                 error "$LFS find found $count != 19 entries after error"
8574 }
8575 run_test 56z "lfs find should continue after an error"
8576
8577 test_56aa() { # LU-5937
8578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8579
8580         local dir=$DIR/$tdir
8581
8582         mkdir $dir
8583         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8584
8585         createmany -o $dir/striped_dir/${tfile}- 1024
8586         local dirs=$($LFS find --size +8k $dir/)
8587
8588         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8589 }
8590 run_test 56aa "lfs find --size under striped dir"
8591
8592 test_56ab() { # LU-10705
8593         test_mkdir $DIR/$tdir
8594         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8595         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8596         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8597         # Flush writes to ensure valid blocks.  Need to be more thorough for
8598         # ZFS, since blocks are not allocated/returned to client immediately.
8599         sync_all_data
8600         wait_zfs_commit ost1 2
8601         cancel_lru_locks osc
8602         ls -ls $DIR/$tdir
8603
8604         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8605
8606         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8607
8608         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8609         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8610
8611         rm -f $DIR/$tdir/$tfile.[123]
8612 }
8613 run_test 56ab "lfs find --blocks"
8614
8615 # LU-11188
8616 test_56aca() {
8617         local dir="$DIR/$tdir"
8618         local perms=(001 002 003 004 005 006 007
8619                      010 020 030 040 050 060 070
8620                      100 200 300 400 500 600 700
8621                      111 222 333 444 555 666 777)
8622         local perm_minus=(8 8 4 8 4 4 2
8623                           8 8 4 8 4 4 2
8624                           8 8 4 8 4 4 2
8625                           4 4 2 4 2 2 1)
8626         local perm_slash=(8  8 12  8 12 12 14
8627                           8  8 12  8 12 12 14
8628                           8  8 12  8 12 12 14
8629                          16 16 24 16 24 24 28)
8630
8631         test_mkdir "$dir"
8632         for perm in ${perms[*]}; do
8633                 touch "$dir/$tfile.$perm"
8634                 chmod $perm "$dir/$tfile.$perm"
8635         done
8636
8637         for ((i = 0; i < ${#perms[*]}; i++)); do
8638                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8639                 (( $num == 1 )) ||
8640                         error "lfs find -perm ${perms[i]}:"\
8641                               "$num != 1"
8642
8643                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8644                 (( $num == ${perm_minus[i]} )) ||
8645                         error "lfs find -perm -${perms[i]}:"\
8646                               "$num != ${perm_minus[i]}"
8647
8648                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8649                 (( $num == ${perm_slash[i]} )) ||
8650                         error "lfs find -perm /${perms[i]}:"\
8651                               "$num != ${perm_slash[i]}"
8652         done
8653 }
8654 run_test 56aca "check lfs find -perm with octal representation"
8655
8656 test_56acb() {
8657         local dir=$DIR/$tdir
8658         # p is the permission of write and execute for user, group and other
8659         # without the umask. It is used to test +wx.
8660         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8661         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8662         local symbolic=(+t  a+t u+t g+t o+t
8663                         g+s u+s o+s +s o+sr
8664                         o=r,ug+o,u+w
8665                         u+ g+ o+ a+ ugo+
8666                         u- g- o- a- ugo-
8667                         u= g= o= a= ugo=
8668                         o=r,ug+o,u+w u=r,a+u,u+w
8669                         g=r,ugo=g,u+w u+x,+X +X
8670                         u+x,u+X u+X u+x,g+X o+r,+X
8671                         u+x,go+X +wx +rwx)
8672
8673         test_mkdir $dir
8674         for perm in ${perms[*]}; do
8675                 touch "$dir/$tfile.$perm"
8676                 chmod $perm "$dir/$tfile.$perm"
8677         done
8678
8679         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8680                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8681
8682                 (( $num == 1 )) ||
8683                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8684         done
8685 }
8686 run_test 56acb "check lfs find -perm with symbolic representation"
8687
8688 test_56acc() {
8689         local dir=$DIR/$tdir
8690         local tests="17777 787 789 abcd
8691                 ug=uu ug=a ug=gu uo=ou urw
8692                 u+xg+x a=r,u+x,"
8693
8694         test_mkdir $dir
8695         for err in $tests; do
8696                 if $LFS find $dir -perm $err 2>/dev/null; then
8697                         error "lfs find -perm $err: parsing should have failed"
8698                 fi
8699         done
8700 }
8701 run_test 56acc "check parsing error for lfs find -perm"
8702
8703 test_56ba() {
8704         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8705                 skip "Need MDS version at least 2.10.50"
8706
8707         # Create composite files with one component
8708         local dir=$DIR/$tdir
8709
8710         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8711         # Create composite files with three components
8712         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8713         # LU-16904 Create plain layout files
8714         lfs setstripe -c 1 $dir/$tfile-{1..10}
8715
8716         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8717
8718         [[ $nfiles == 10 ]] ||
8719                 error "lfs find -E 1M found $nfiles != 10 files"
8720
8721         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8722         [[ $nfiles == 25 ]] ||
8723                 error "lfs find ! -E 1M found $nfiles != 25 files"
8724
8725         # All files have a component that starts at 0
8726         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8727         [[ $nfiles == 35 ]] ||
8728                 error "lfs find --component-start 0 - $nfiles != 35 files"
8729
8730         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8731         [[ $nfiles == 15 ]] ||
8732                 error "lfs find --component-start 2M - $nfiles != 15 files"
8733
8734         # All files created here have a componenet that does not starts at 2M
8735         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8736         [[ $nfiles == 35 ]] ||
8737                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8738
8739         # Find files with a specified number of components
8740         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8741         [[ $nfiles == 15 ]] ||
8742                 error "lfs find --component-count 3 - $nfiles != 15 files"
8743
8744         # Remember non-composite files have a component count of zero
8745         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8746         [[ $nfiles == 10 ]] ||
8747                 error "lfs find --component-count 0 - $nfiles != 10 files"
8748
8749         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8750         [[ $nfiles == 20 ]] ||
8751                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8752
8753         # All files have a flag called "init"
8754         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8755         [[ $nfiles == 35 ]] ||
8756                 error "lfs find --component-flags init - $nfiles != 35 files"
8757
8758         # Multi-component files will have a component not initialized
8759         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8760         [[ $nfiles == 15 ]] ||
8761                 error "lfs find !--component-flags init - $nfiles != 15 files"
8762
8763         rm -rf $dir
8764
8765 }
8766 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8767
8768 test_56ca() {
8769         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8770                 skip "Need MDS version at least 2.10.57"
8771
8772         local td=$DIR/$tdir
8773         local tf=$td/$tfile
8774         local dir
8775         local nfiles
8776         local cmd
8777         local i
8778         local j
8779
8780         # create mirrored directories and mirrored files
8781         mkdir $td || error "mkdir $td failed"
8782         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8783         createmany -o $tf- 10 || error "create $tf- failed"
8784
8785         for i in $(seq 2); do
8786                 dir=$td/dir$i
8787                 mkdir $dir || error "mkdir $dir failed"
8788                 $LFS mirror create -N$((3 + i)) $dir ||
8789                         error "create mirrored dir $dir failed"
8790                 createmany -o $dir/$tfile- 10 ||
8791                         error "create $dir/$tfile- failed"
8792         done
8793
8794         # change the states of some mirrored files
8795         echo foo > $tf-6
8796         for i in $(seq 2); do
8797                 dir=$td/dir$i
8798                 for j in $(seq 4 9); do
8799                         echo foo > $dir/$tfile-$j
8800                 done
8801         done
8802
8803         # find mirrored files with specific mirror count
8804         cmd="$LFS find --mirror-count 3 --type f $td"
8805         nfiles=$($cmd | wc -l)
8806         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8807
8808         cmd="$LFS find ! --mirror-count 3 --type f $td"
8809         nfiles=$($cmd | wc -l)
8810         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8811
8812         cmd="$LFS find --mirror-count +2 --type f $td"
8813         nfiles=$($cmd | wc -l)
8814         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8815
8816         cmd="$LFS find --mirror-count -6 --type f $td"
8817         nfiles=$($cmd | wc -l)
8818         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8819
8820         # find mirrored files with specific file state
8821         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8822         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8823
8824         cmd="$LFS find --mirror-state=ro --type f $td"
8825         nfiles=$($cmd | wc -l)
8826         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8827
8828         cmd="$LFS find ! --mirror-state=ro --type f $td"
8829         nfiles=$($cmd | wc -l)
8830         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8831
8832         cmd="$LFS find --mirror-state=wp --type f $td"
8833         nfiles=$($cmd | wc -l)
8834         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8835
8836         cmd="$LFS find ! --mirror-state=sp --type f $td"
8837         nfiles=$($cmd | wc -l)
8838         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8839 }
8840 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8841
8842 test_56da() { # LU-14179
8843         local path=$DIR/$tdir
8844
8845         test_mkdir $path
8846         cd $path
8847
8848         local longdir=$(str_repeat 'a' 255)
8849
8850         for i in {1..15}; do
8851                 path=$path/$longdir
8852                 test_mkdir $longdir
8853                 cd $longdir
8854         done
8855
8856         local len=${#path}
8857         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8858
8859         test_mkdir $lastdir
8860         cd $lastdir
8861         # PATH_MAX-1
8862         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8863
8864         # NAME_MAX
8865         touch $(str_repeat 'f' 255)
8866
8867         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8868                 error "lfs find reported an error"
8869
8870         rm -rf $DIR/$tdir
8871 }
8872 run_test 56da "test lfs find with long paths"
8873
8874 test_56ea() { #LU-10378
8875         local path=$DIR/$tdir
8876         local pool=$TESTNAME
8877
8878         # Create ost pool
8879         pool_add $pool || error "pool_add $pool failed"
8880         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8881                 error "adding targets to $pool failed"
8882
8883         # Set default pool on directory before creating file
8884         mkdir $path || error "mkdir $path failed"
8885         $LFS setstripe -p $pool $path ||
8886                 error "set OST pool on $pool failed"
8887         touch $path/$tfile || error "touch $path/$tfile failed"
8888
8889         # Compare basic file attributes from -printf and stat
8890         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8891         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8892
8893         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8894                 error "Attrs from lfs find and stat don't match"
8895
8896         # Compare Lustre attributes from lfs find and lfs getstripe
8897         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8898         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8899         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8900         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8901         local fpool=$($LFS getstripe --pool $path/$tfile)
8902         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8903
8904         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8905                 error "Attrs from lfs find and lfs getstripe don't match"
8906
8907         # Verify behavior for unknown escape/format sequences
8908         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8909
8910         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8911                 error "Escape/format codes don't match"
8912 }
8913 run_test 56ea "test lfs find -printf option"
8914
8915 test_56eb() {
8916         local dir=$DIR/$tdir
8917         local subdir_1=$dir/subdir_1
8918
8919         test_mkdir -p $subdir_1
8920         ln -s subdir_1 $dir/link_1
8921
8922         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8923                 error "symlink is not followed"
8924
8925         $LFS getstripe --no-follow $dir |
8926                 grep "^$dir/link_1 has no stripe info$" ||
8927                 error "symlink should not have stripe info"
8928
8929         touch $dir/testfile
8930         ln -s testfile $dir/file_link_2
8931
8932         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8933                 error "symlink is not followed"
8934
8935         $LFS getstripe --no-follow $dir |
8936                 grep "^$dir/file_link_2 has no stripe info$" ||
8937                 error "symlink should not have stripe info"
8938 }
8939 run_test 56eb "check lfs getstripe on symlink"
8940
8941 test_56ec() {
8942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8943         local dir=$DIR/$tdir
8944         local srcfile=$dir/srcfile
8945         local srcyaml=$dir/srcyaml
8946         local destfile=$dir/destfile
8947
8948         test_mkdir -p $dir
8949
8950         $LFS setstripe -i 1 $srcfile
8951         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8952         # if the setstripe yaml parsing fails for any reason, the command can
8953         # randomly assign the correct OST index, leading to an erroneous
8954         # success. but the chance of false success is low enough that a
8955         # regression should still be quickly caught.
8956         $LFS setstripe --yaml=$srcyaml $destfile
8957
8958         local srcindex=$($LFS getstripe -i $srcfile)
8959         local destindex=$($LFS getstripe -i $destfile)
8960
8961         if [[ ! $srcindex -eq $destindex ]]; then
8962                 error "setstripe did not set OST index correctly"
8963         fi
8964 }
8965 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8966
8967 test_56eda() {
8968         local dir=$DIR/$tdir
8969         local subdir=$dir/subdir
8970         local file1=$dir/$tfile
8971         local file2=$dir/$tfile\2
8972         local link=$dir/$tfile-link
8973         local nfiles
8974
8975         test_mkdir -p $dir
8976         $LFS setdirstripe -c1 $subdir
8977         touch $file1
8978         touch $file2
8979         ln $file2 $link
8980
8981         nfiles=$($LFS find --links 1 $dir | wc -l)
8982         (( $nfiles == 1 )) ||
8983                 error "lfs find --links expected 1 file, got $nfiles"
8984
8985         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
8986         (( $nfiles == 2 )) ||
8987                 error "lfs find --links expected 2 files, got $nfiles"
8988
8989         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
8990         (( $nfiles == 1 )) ||
8991                 error "lfs find --links expected 1 directory, got $nfiles"
8992 }
8993 run_test 56eda "check lfs find --links"
8994
8995 test_56edb() {
8996         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
8997
8998         local dir=$DIR/$tdir
8999         local stripedir=$dir/stripedir
9000         local nfiles
9001
9002         test_mkdir -p $dir
9003
9004         $LFS setdirstripe -c2 $stripedir
9005
9006         $LFS getdirstripe $stripedir
9007
9008         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9009         (( $nfiles == 1 )) ||
9010                 error "lfs find --links expected 1 directory, got $nfiles"
9011 }
9012 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9013
9014 test_56ef() {
9015         local dir=$DIR/$tdir
9016         local dir1=$dir/d1
9017         local dir2=$dir/d2
9018         local nfiles
9019         local err_msg
9020
9021         test_mkdir -p $dir
9022
9023         mkdir $dir1
9024         mkdir $dir2
9025
9026         touch $dir1/f
9027         touch $dir2/f
9028
9029         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9030         (( $nfiles == 2 )) ||
9031                 error "(1) lfs find expected 2 files, got $nfiles"
9032
9033         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9034         (( $nfiles == 2 )) ||
9035                 error "(2) lfs find expected 2 files, got $nfiles"
9036
9037         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9038         (( $nfiles == 2 )) ||
9039                 error "(3) lfs find expected 2 files, got $nfiles"
9040
9041         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9042         [[ $err_msg =~ "No such file or directory" ]] ||
9043                 error "expected standard error message, got: '$err_msg'"
9044 }
9045 run_test 56ef "lfs find with multiple paths"
9046
9047 test_56eg() {
9048         local dir=$DIR/$tdir
9049         local found
9050
9051         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9052
9053         test_mkdir -p $dir
9054
9055         touch $dir/$tfile
9056         ln -s $dir/$tfile $dir/$tfile.symlink
9057         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9058         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9059                 $dir/$tfile.symlink
9060         setfattr --no-dereference -n "trusted.common" \
9061                 $dir/{$tfile,$tfile.symlink}
9062
9063         found=$($LFS find -xattr "trusted.*=test_target" \
9064                 -xattr "trusted.common" $dir)
9065         [[ "$found" == "$dir/$tfile" ]] || {
9066                 getfattr -d -m trusted.* $dir/$tfile
9067                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9068         }
9069
9070         found=$($LFS find -xattr "trusted.*=test_link" \
9071                 -xattr "trusted.common" $dir)
9072         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9073                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9074                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9075         }
9076
9077         rm -f $dir/*
9078
9079         touch $dir/$tfile.1
9080         touch $dir/$tfile.2
9081         setfattr -n "user.test" -v "1" $dir/$tfile.1
9082         setfattr -n "user.test" -v "2" $dir/$tfile.2
9083         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9084
9085         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9086         [[ "$found" == "$dir/$tfile.1" ]] || {
9087                 getfattr -d $dir/$tfile.1
9088                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9089         }
9090
9091         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9092         [[ "$found" == "$dir/$tfile.2" ]] || {
9093                 getfattr -d $dir/$tfile.2
9094                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9095         }
9096
9097         setfattr -n "user.empty" $dir/$tfile.1
9098         found=$($LFS find -xattr "user.empty" $dir)
9099         [[ "$found" == "$dir/$tfile.1" ]] || {
9100                 getfattr -d $dir/$tfile.1
9101                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9102         }
9103
9104         # setfattr command normally does not store terminating null byte
9105         # when writing a string as an xattr value.
9106         #
9107         # In order to test matching a value string that includes a terminating
9108         # null, explicitly encode the string "test\0" with the null terminator.
9109         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9110         found=$($LFS find -xattr "user.test=test" $dir)
9111         [[ "$found" == "$dir/$tfile.1" ]] || {
9112                 getfattr -d --encoding=hex $dir/$tfile.1
9113                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9114         }
9115 }
9116 run_test 56eg "lfs find -xattr"
9117
9118 test_57a() {
9119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9120         # note test will not do anything if MDS is not local
9121         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9122                 skip_env "ldiskfs only test"
9123         fi
9124         remote_mds_nodsh && skip "remote MDS with nodsh"
9125
9126         local MNTDEV="osd*.*MDT*.mntdev"
9127         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9128         [ -z "$DEV" ] && error "can't access $MNTDEV"
9129         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9130                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9131                         error "can't access $DEV"
9132                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9133                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9134                 rm $TMP/t57a.dump
9135         done
9136 }
9137 run_test 57a "verify MDS filesystem created with large inodes =="
9138
9139 test_57b() {
9140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9141         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9142                 skip_env "ldiskfs only test"
9143         fi
9144         remote_mds_nodsh && skip "remote MDS with nodsh"
9145
9146         local dir=$DIR/$tdir
9147         local filecount=100
9148         local file1=$dir/f1
9149         local fileN=$dir/f$filecount
9150
9151         rm -rf $dir || error "removing $dir"
9152         test_mkdir -c1 $dir
9153         local mdtidx=$($LFS getstripe -m $dir)
9154         local mdtname=MDT$(printf %04x $mdtidx)
9155         local facet=mds$((mdtidx + 1))
9156
9157         echo "mcreating $filecount files"
9158         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9159
9160         # verify that files do not have EAs yet
9161         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9162                 error "$file1 has an EA"
9163         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9164                 error "$fileN has an EA"
9165
9166         sync
9167         sleep 1
9168         df $dir  #make sure we get new statfs data
9169         local mdsfree=$(do_facet $facet \
9170                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9171         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9172         local file
9173
9174         echo "opening files to create objects/EAs"
9175         for file in $(seq -f $dir/f%g 1 $filecount); do
9176                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9177                         error "opening $file"
9178         done
9179
9180         # verify that files have EAs now
9181         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9182                 error "$file1 missing EA"
9183         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9184                 error "$fileN missing EA"
9185
9186         sleep 1  #make sure we get new statfs data
9187         df $dir
9188         local mdsfree2=$(do_facet $facet \
9189                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9190         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9191
9192         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9193                 if [ "$mdsfree" != "$mdsfree2" ]; then
9194                         error "MDC before $mdcfree != after $mdcfree2"
9195                 else
9196                         echo "MDC before $mdcfree != after $mdcfree2"
9197                         echo "unable to confirm if MDS has large inodes"
9198                 fi
9199         fi
9200         rm -rf $dir
9201 }
9202 run_test 57b "default LOV EAs are stored inside large inodes ==="
9203
9204 test_58() {
9205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9206         [ -z "$(which wiretest 2>/dev/null)" ] &&
9207                         skip_env "could not find wiretest"
9208
9209         wiretest
9210 }
9211 run_test 58 "verify cross-platform wire constants =============="
9212
9213 test_59() {
9214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9215
9216         echo "touch 130 files"
9217         createmany -o $DIR/f59- 130
9218         echo "rm 130 files"
9219         unlinkmany $DIR/f59- 130
9220         sync
9221         # wait for commitment of removal
9222         wait_delete_completed
9223 }
9224 run_test 59 "verify cancellation of llog records async ========="
9225
9226 TEST60_HEAD="test_60 run $RANDOM"
9227 test_60a() {
9228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9229         remote_mgs_nodsh && skip "remote MGS with nodsh"
9230         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9231                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9232                         skip_env "missing subtest run-llog.sh"
9233
9234         log "$TEST60_HEAD - from kernel mode"
9235         do_facet mgs "$LCTL dk > /dev/null"
9236         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9237         do_facet mgs $LCTL dk > $TMP/$tfile
9238
9239         # LU-6388: test llog_reader
9240         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9241         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9242         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9243                         skip_env "missing llog_reader"
9244         local fstype=$(facet_fstype mgs)
9245         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9246                 skip_env "Only for ldiskfs or zfs type mgs"
9247
9248         local mntpt=$(facet_mntpt mgs)
9249         local mgsdev=$(mgsdevname 1)
9250         local fid_list
9251         local fid
9252         local rec_list
9253         local rec
9254         local rec_type
9255         local obj_file
9256         local path
9257         local seq
9258         local oid
9259         local pass=true
9260
9261         #get fid and record list
9262         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9263                 tail -n 4))
9264         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9265                 tail -n 4))
9266         #remount mgs as ldiskfs or zfs type
9267         stop mgs || error "stop mgs failed"
9268         mount_fstype mgs || error "remount mgs failed"
9269         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9270                 fid=${fid_list[i]}
9271                 rec=${rec_list[i]}
9272                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9273                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9274                 oid=$((16#$oid))
9275
9276                 case $fstype in
9277                         ldiskfs )
9278                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9279                         zfs )
9280                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9281                 esac
9282                 echo "obj_file is $obj_file"
9283                 do_facet mgs $llog_reader $obj_file
9284
9285                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9286                         awk '{ print $3 }' | sed -e "s/^type=//g")
9287                 if [ $rec_type != $rec ]; then
9288                         echo "FAILED test_60a wrong record type $rec_type," \
9289                               "should be $rec"
9290                         pass=false
9291                         break
9292                 fi
9293
9294                 #check obj path if record type is LLOG_LOGID_MAGIC
9295                 if [ "$rec" == "1064553b" ]; then
9296                         path=$(do_facet mgs $llog_reader $obj_file |
9297                                 grep "path=" | awk '{ print $NF }' |
9298                                 sed -e "s/^path=//g")
9299                         if [ $obj_file != $mntpt/$path ]; then
9300                                 echo "FAILED test_60a wrong obj path" \
9301                                       "$montpt/$path, should be $obj_file"
9302                                 pass=false
9303                                 break
9304                         fi
9305                 fi
9306         done
9307         rm -f $TMP/$tfile
9308         #restart mgs before "error", otherwise it will block the next test
9309         stop mgs || error "stop mgs failed"
9310         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9311         $pass || error "test failed, see FAILED test_60a messages for specifics"
9312 }
9313 run_test 60a "llog_test run from kernel module and test llog_reader"
9314
9315 test_60b() { # bug 6411
9316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9317
9318         dmesg > $DIR/$tfile
9319         LLOG_COUNT=$(do_facet mgs dmesg |
9320                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9321                           /llog_[a-z]*.c:[0-9]/ {
9322                                 if (marker)
9323                                         from_marker++
9324                                 from_begin++
9325                           }
9326                           END {
9327                                 if (marker)
9328                                         print from_marker
9329                                 else
9330                                         print from_begin
9331                           }")
9332
9333         [[ $LLOG_COUNT -gt 120 ]] &&
9334                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9335 }
9336 run_test 60b "limit repeated messages from CERROR/CWARN"
9337
9338 test_60c() {
9339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9340
9341         echo "create 5000 files"
9342         createmany -o $DIR/f60c- 5000
9343 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9344         lctl set_param fail_loc=0x80000137
9345         unlinkmany $DIR/f60c- 5000
9346         lctl set_param fail_loc=0
9347 }
9348 run_test 60c "unlink file when mds full"
9349
9350 test_60d() {
9351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9352
9353         SAVEPRINTK=$(lctl get_param -n printk)
9354         # verify "lctl mark" is even working"
9355         MESSAGE="test message ID $RANDOM $$"
9356         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9357         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9358
9359         lctl set_param printk=0 || error "set lnet.printk failed"
9360         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9361         MESSAGE="new test message ID $RANDOM $$"
9362         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9363         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9364         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9365
9366         lctl set_param -n printk="$SAVEPRINTK"
9367 }
9368 run_test 60d "test printk console message masking"
9369
9370 test_60e() {
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372         remote_mds_nodsh && skip "remote MDS with nodsh"
9373
9374         touch $DIR/$tfile
9375 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9376         do_facet mds1 lctl set_param fail_loc=0x15b
9377         rm $DIR/$tfile
9378 }
9379 run_test 60e "no space while new llog is being created"
9380
9381 test_60f() {
9382         local old_path=$($LCTL get_param -n debug_path)
9383
9384         stack_trap "$LCTL set_param debug_path=$old_path"
9385         stack_trap "rm -f $TMP/$tfile*"
9386         rm -f $TMP/$tfile* 2> /dev/null
9387         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9388         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9389         test_mkdir $DIR/$tdir
9390         # retry in case the open is cached and not released
9391         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9392                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9393                 sleep 0.1
9394         done
9395         ls $TMP/$tfile*
9396         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9397 }
9398 run_test 60f "change debug_path works"
9399
9400 test_60g() {
9401         local pid
9402         local i
9403
9404         test_mkdir -c $MDSCOUNT $DIR/$tdir
9405
9406         (
9407                 local index=0
9408                 while true; do
9409                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9410                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9411                                 2>/dev/null
9412                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9413                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9414                         index=$((index + 1))
9415                 done
9416         ) &
9417
9418         pid=$!
9419
9420         for i in {0..100}; do
9421                 # define OBD_FAIL_OSD_TXN_START    0x19a
9422                 local index=$((i % MDSCOUNT + 1))
9423
9424                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9425                         > /dev/null
9426                 sleep 0.01
9427         done
9428
9429         kill -9 $pid
9430
9431         for i in $(seq $MDSCOUNT); do
9432                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9433         done
9434
9435         mkdir $DIR/$tdir/new || error "mkdir failed"
9436         rmdir $DIR/$tdir/new || error "rmdir failed"
9437
9438         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9439                 -t namespace
9440         for i in $(seq $MDSCOUNT); do
9441                 wait_update_facet mds$i "$LCTL get_param -n \
9442                         mdd.$(facet_svc mds$i).lfsck_namespace |
9443                         awk '/^status/ { print \\\$2 }'" "completed"
9444         done
9445
9446         ls -R $DIR/$tdir
9447         rm -rf $DIR/$tdir || error "rmdir failed"
9448 }
9449 run_test 60g "transaction abort won't cause MDT hung"
9450
9451 test_60h() {
9452         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9453                 skip "Need MDS version at least 2.12.52"
9454         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9455
9456         local f
9457
9458         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9459         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9460         for fail_loc in 0x80000188 0x80000189; do
9461                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9462                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9463                         error "mkdir $dir-$fail_loc failed"
9464                 for i in {0..10}; do
9465                         # create may fail on missing stripe
9466                         echo $i > $DIR/$tdir-$fail_loc/$i
9467                 done
9468                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9469                         error "getdirstripe $tdir-$fail_loc failed"
9470                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9471                         error "migrate $tdir-$fail_loc failed"
9472                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9473                         error "getdirstripe $tdir-$fail_loc failed"
9474                 pushd $DIR/$tdir-$fail_loc
9475                 for f in *; do
9476                         echo $f | cmp $f - || error "$f data mismatch"
9477                 done
9478                 popd
9479                 rm -rf $DIR/$tdir-$fail_loc
9480         done
9481 }
9482 run_test 60h "striped directory with missing stripes can be accessed"
9483
9484 function t60i_load() {
9485         mkdir $DIR/$tdir
9486         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9487         $LCTL set_param fail_loc=0x131c fail_val=1
9488         for ((i=0; i<5000; i++)); do
9489                 touch $DIR/$tdir/f$i
9490         done
9491 }
9492
9493 test_60i() {
9494         changelog_register || error "changelog_register failed"
9495         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9496         changelog_users $SINGLEMDS | grep -q $cl_user ||
9497                 error "User $cl_user not found in changelog_users"
9498         changelog_chmask "ALL"
9499         t60i_load &
9500         local PID=$!
9501         for((i=0; i<100; i++)); do
9502                 changelog_dump >/dev/null ||
9503                         error "can't read changelog"
9504         done
9505         kill $PID
9506         wait $PID
9507         changelog_deregister || error "changelog_deregister failed"
9508         $LCTL set_param fail_loc=0
9509 }
9510 run_test 60i "llog: new record vs reader race"
9511
9512 test_60j() {
9513         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9514                 skip "need MDS version at least 2.15.50"
9515         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9516         remote_mds_nodsh && skip "remote MDS with nodsh"
9517         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9518
9519         changelog_users $SINGLEMDS | grep "^cl" &&
9520                 skip "active changelog user"
9521
9522         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9523
9524         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9525                 skip_env "missing llog_reader"
9526
9527         mkdir_on_mdt0 $DIR/$tdir
9528
9529         local f=$DIR/$tdir/$tfile
9530         local mdt_dev
9531         local tmpfile
9532         local plain
9533
9534         changelog_register || error "cannot register changelog user"
9535
9536         # set changelog_mask to ALL
9537         changelog_chmask "ALL"
9538         changelog_clear
9539
9540         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9541         unlinkmany ${f}- 100 || error "unlinkmany failed"
9542
9543         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9544         mdt_dev=$(facet_device $SINGLEMDS)
9545
9546         do_facet $SINGLEMDS sync
9547         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9548                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9549                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9550
9551         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9552
9553         # if $tmpfile is not on EXT3 filesystem for some reason
9554         [[ ${plain:0:1} == 'O' ]] ||
9555                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9556
9557         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9558                 $mdt_dev; stat -c %s $tmpfile")
9559         echo "Truncate llog from $size to $((size - size % 8192))"
9560         size=$((size - size % 8192))
9561         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9562         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9563                 grep -c 'in bitmap only')
9564         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9565
9566         size=$((size - 9000))
9567         echo "Corrupt llog in the middle at $size"
9568         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9569                 count=333 conv=notrunc
9570         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9571                 grep -c 'next chunk')
9572         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9573 }
9574 run_test 60j "llog_reader reports corruptions"
9575
9576 test_61a() {
9577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9578
9579         f="$DIR/f61"
9580         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9581         cancel_lru_locks osc
9582         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9583         sync
9584 }
9585 run_test 61a "mmap() writes don't make sync hang ================"
9586
9587 test_61b() {
9588         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9589 }
9590 run_test 61b "mmap() of unstriped file is successful"
9591
9592 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9593 # Though this test is irrelevant anymore, it helped to reveal some
9594 # other grant bugs (LU-4482), let's keep it.
9595 test_63a() {   # was test_63
9596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9597
9598         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9599
9600         for i in `seq 10` ; do
9601                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9602                 sleep 5
9603                 kill $!
9604                 sleep 1
9605         done
9606
9607         rm -f $DIR/f63 || true
9608 }
9609 run_test 63a "Verify oig_wait interruption does not crash ======="
9610
9611 # bug 2248 - async write errors didn't return to application on sync
9612 # bug 3677 - async write errors left page locked
9613 test_63b() {
9614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9615
9616         debugsave
9617         lctl set_param debug=-1
9618
9619         # ensure we have a grant to do async writes
9620         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9621         rm $DIR/$tfile
9622
9623         sync    # sync lest earlier test intercept the fail_loc
9624
9625         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9626         lctl set_param fail_loc=0x80000406
9627         $MULTIOP $DIR/$tfile Owy && \
9628                 error "sync didn't return ENOMEM"
9629         sync; sleep 2; sync     # do a real sync this time to flush page
9630         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9631                 error "locked page left in cache after async error" || true
9632         debugrestore
9633 }
9634 run_test 63b "async write errors should be returned to fsync ==="
9635
9636 test_64a () {
9637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9638
9639         lfs df $DIR
9640         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9641 }
9642 run_test 64a "verify filter grant calculations (in kernel) ====="
9643
9644 test_64b () {
9645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9646
9647         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9648 }
9649 run_test 64b "check out-of-space detection on client"
9650
9651 test_64c() {
9652         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9653 }
9654 run_test 64c "verify grant shrink"
9655
9656 import_param() {
9657         local tgt=$1
9658         local param=$2
9659
9660         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9661 }
9662
9663 # this does exactly what osc_request.c:osc_announce_cached() does in
9664 # order to calculate max amount of grants to ask from server
9665 want_grant() {
9666         local tgt=$1
9667
9668         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9669         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9670
9671         ((rpc_in_flight++));
9672         nrpages=$((nrpages * rpc_in_flight))
9673
9674         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9675
9676         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9677
9678         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9679         local undirty=$((nrpages * PAGE_SIZE))
9680
9681         local max_extent_pages
9682         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9683         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9684         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9685         local grant_extent_tax
9686         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9687
9688         undirty=$((undirty + nrextents * grant_extent_tax))
9689
9690         echo $undirty
9691 }
9692
9693 # this is size of unit for grant allocation. It should be equal to
9694 # what tgt_grant.c:tgt_grant_chunk() calculates
9695 grant_chunk() {
9696         local tgt=$1
9697         local max_brw_size
9698         local grant_extent_tax
9699
9700         max_brw_size=$(import_param $tgt max_brw_size)
9701
9702         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9703
9704         echo $(((max_brw_size + grant_extent_tax) * 2))
9705 }
9706
9707 test_64d() {
9708         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9709                 skip "OST < 2.10.55 doesn't limit grants enough"
9710
9711         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9712
9713         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9714                 skip "no grant_param connect flag"
9715
9716         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9717
9718         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9719         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9720
9721
9722         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9723         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9724
9725         $LFS setstripe $DIR/$tfile -i 0 -c 1
9726         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9727         ddpid=$!
9728
9729         while kill -0 $ddpid; do
9730                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9731
9732                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9733                         kill $ddpid
9734                         error "cur_grant $cur_grant > $max_cur_granted"
9735                 fi
9736
9737                 sleep 1
9738         done
9739 }
9740 run_test 64d "check grant limit exceed"
9741
9742 check_grants() {
9743         local tgt=$1
9744         local expected=$2
9745         local msg=$3
9746         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9747
9748         ((cur_grants == expected)) ||
9749                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9750 }
9751
9752 round_up_p2() {
9753         echo $((($1 + $2 - 1) & ~($2 - 1)))
9754 }
9755
9756 test_64e() {
9757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9758         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9759                 skip "Need OSS version at least 2.11.56"
9760
9761         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9762         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9763         $LCTL set_param debug=+cache
9764
9765         # Remount client to reset grant
9766         remount_client $MOUNT || error "failed to remount client"
9767         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9768
9769         local init_grants=$(import_param $osc_tgt initial_grant)
9770
9771         check_grants $osc_tgt $init_grants "init grants"
9772
9773         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9774         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9775         local gbs=$(import_param $osc_tgt grant_block_size)
9776
9777         # write random number of bytes from max_brw_size / 4 to max_brw_size
9778         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9779         # align for direct io
9780         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9781         # round to grant consumption unit
9782         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9783
9784         local grants=$((wb_round_up + extent_tax))
9785
9786         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9787         stack_trap "rm -f $DIR/$tfile"
9788
9789         # define OBD_FAIL_TGT_NO_GRANT 0x725
9790         # make the server not grant more back
9791         do_facet ost1 $LCTL set_param fail_loc=0x725
9792         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9793
9794         do_facet ost1 $LCTL set_param fail_loc=0
9795
9796         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9797
9798         rm -f $DIR/$tfile || error "rm failed"
9799
9800         # Remount client to reset grant
9801         remount_client $MOUNT || error "failed to remount client"
9802         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9803
9804         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9805
9806         # define OBD_FAIL_TGT_NO_GRANT 0x725
9807         # make the server not grant more back
9808         do_facet ost1 $LCTL set_param fail_loc=0x725
9809         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9810         do_facet ost1 $LCTL set_param fail_loc=0
9811
9812         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9813 }
9814 run_test 64e "check grant consumption (no grant allocation)"
9815
9816 test_64f() {
9817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9818
9819         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9820         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9821         $LCTL set_param debug=+cache
9822
9823         # Remount client to reset grant
9824         remount_client $MOUNT || error "failed to remount client"
9825         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9826
9827         local init_grants=$(import_param $osc_tgt initial_grant)
9828         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9829         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9830         local gbs=$(import_param $osc_tgt grant_block_size)
9831         local chunk=$(grant_chunk $osc_tgt)
9832
9833         # write random number of bytes from max_brw_size / 4 to max_brw_size
9834         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9835         # align for direct io
9836         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9837         # round to grant consumption unit
9838         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9839
9840         local grants=$((wb_round_up + extent_tax))
9841
9842         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9843         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9844                 error "error writing to $DIR/$tfile"
9845
9846         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9847                 "direct io with grant allocation"
9848
9849         rm -f $DIR/$tfile || error "rm failed"
9850
9851         # Remount client to reset grant
9852         remount_client $MOUNT || error "failed to remount client"
9853         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9854
9855         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9856
9857         # Testing that buffered IO consumes grant on the client
9858
9859         # Delay the RPC on the server so it's guaranteed to not complete even
9860         # if the RPC is sent from the client
9861         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9862         $LCTL set_param fail_loc=0x50a fail_val=3
9863         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9864                 error "error writing to $DIR/$tfile with buffered IO"
9865
9866         check_grants $osc_tgt $((init_grants - grants)) \
9867                 "buffered io, not write rpc"
9868
9869         # Clear the fail loc and do a sync on the client
9870         $LCTL set_param fail_loc=0 fail_val=0
9871         sync
9872
9873         # RPC is now known to have sent
9874         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9875                 "buffered io, one RPC"
9876 }
9877 run_test 64f "check grant consumption (with grant allocation)"
9878
9879 test_64g() {
9880         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9881                 skip "Need MDS version at least 2.14.56"
9882
9883         local mdts=$(comma_list $(mdts_nodes))
9884
9885         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9886                         tr '\n' ' ')
9887         stack_trap "$LCTL set_param $old"
9888
9889         # generate dirty pages and increase dirty granted on MDT
9890         stack_trap "rm -f $DIR/$tfile-*"
9891         for (( i = 0; i < 10; i++)); do
9892                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9893                         error "can't set stripe"
9894                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9895                         error "can't dd"
9896                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9897                         $LFS getstripe $DIR/$tfile-$i
9898                         error "not DoM file"
9899                 }
9900         done
9901
9902         # flush dirty pages
9903         sync
9904
9905         # wait until grant shrink reset grant dirty on MDTs
9906         for ((i = 0; i < 120; i++)); do
9907                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9908                         awk '{sum=sum+$1} END {print sum}')
9909                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9910                 echo "$grant_dirty grants, $vm_dirty pages"
9911                 (( grant_dirty + vm_dirty == 0 )) && break
9912                 (( i == 3 )) && sync &&
9913                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9914                 sleep 1
9915         done
9916
9917         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9918                 awk '{sum=sum+$1} END {print sum}')
9919         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9920 }
9921 run_test 64g "grant shrink on MDT"
9922
9923 test_64h() {
9924         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9925                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9926
9927         local instance=$($LFS getname -i $DIR)
9928         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9929         local num_exps=$(do_facet ost1 \
9930             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9931         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9932         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9933         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9934
9935         # 10MiB is for file to be written, max_brw_size * 16 *
9936         # num_exps is space reserve so that tgt_grant_shrink() decided
9937         # to not shrink
9938         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9939         (( avail * 1024 < expect )) &&
9940                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9941
9942         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9943         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9944         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9945         $LCTL set_param osc.*OST0000*.grant_shrink=1
9946         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9947
9948         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9949         stack_trap "rm -f $DIR/$tfile"
9950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9951
9952         # drop cache so that coming read would do rpc
9953         cancel_lru_locks osc
9954
9955         # shrink interval is set to 10, pause for 7 seconds so that
9956         # grant thread did not wake up yet but coming read entered
9957         # shrink mode for rpc (osc_should_shrink_grant())
9958         sleep 7
9959
9960         declare -a cur_grant_bytes
9961         declare -a tot_granted
9962         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9963         tot_granted[0]=$(do_facet ost1 \
9964             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9965
9966         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9967
9968         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9969         tot_granted[1]=$(do_facet ost1 \
9970             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9971
9972         # grant change should be equal on both sides
9973         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9974                 tot_granted[0] - tot_granted[1])) ||
9975                 error "grant change mismatch, "                                \
9976                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9977                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9978 }
9979 run_test 64h "grant shrink on read"
9980
9981 test_64i() {
9982         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9983                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9984
9985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9986         remote_ost_nodsh && skip "remote OSTs with nodsh"
9987
9988         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9989         stack_trap "rm -f $DIR/$tfile"
9990
9991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9992
9993         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9994         local instance=$($LFS getname -i $DIR)
9995
9996         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9997         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9998
9999         # shrink grants and simulate rpc loss
10000         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10001         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10002         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10003
10004         fail ost1
10005
10006         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10007
10008         local testid=$(echo $TESTNAME | tr '_' ' ')
10009
10010         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10011                 grep "GRANT, real grant" &&
10012                 error "client has more grants then it owns" || true
10013 }
10014 run_test 64i "shrink on reconnect"
10015
10016 # bug 1414 - set/get directories' stripe info
10017 test_65a() {
10018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10019
10020         # LU-16904 check if the root is set as PFL layout
10021         local numcomp=$($LFS getstripe --component-count $MOUNT)
10022         [ $numcomp -eq 0 ] || skip "Skip test_65a for PFL layout"
10023
10024         test_mkdir $DIR/$tdir
10025         touch $DIR/$tdir/f1
10026         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10027 }
10028 run_test 65a "directory with no stripe info"
10029
10030 test_65b() {
10031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10032
10033         test_mkdir $DIR/$tdir
10034         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10035
10036         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10037                                                 error "setstripe"
10038         touch $DIR/$tdir/f2
10039         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10040 }
10041 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10042
10043 test_65c() {
10044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10045         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10046
10047         test_mkdir $DIR/$tdir
10048         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10049
10050         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10051                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10052         touch $DIR/$tdir/f3
10053         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10054 }
10055 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10056
10057 test_65d() {
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059
10060         test_mkdir $DIR/$tdir
10061         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10062         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10063
10064         if [[ $STRIPECOUNT -le 0 ]]; then
10065                 sc=1
10066         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10067                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10068                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10069         else
10070                 sc=$(($STRIPECOUNT - 1))
10071         fi
10072         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10073         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10074         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10075                 error "lverify failed"
10076 }
10077 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10078
10079 test_65e() {
10080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10081
10082         # LU-16904 delete layout when root is set as PFL layout
10083         save_layout_restore_at_exit $MOUNT
10084         $LFS setstripe -d $MOUNT || error "setstripe failed"
10085
10086         test_mkdir $DIR/$tdir
10087
10088         $LFS setstripe $DIR/$tdir || error "setstripe"
10089         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10090                                         error "no stripe info failed"
10091         touch $DIR/$tdir/f6
10092         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10093 }
10094 run_test 65e "directory setstripe defaults"
10095
10096 test_65f() {
10097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10098
10099         test_mkdir $DIR/${tdir}f
10100         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10101                 error "setstripe succeeded" || true
10102 }
10103 run_test 65f "dir setstripe permission (should return error) ==="
10104
10105 test_65g() {
10106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10107
10108         # LU-16904 delete layout when root is set as PFL layout
10109         save_layout_restore_at_exit $MOUNT
10110         $LFS setstripe -d $MOUNT || error "setstripe failed"
10111
10112         test_mkdir $DIR/$tdir
10113         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10114
10115         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10116                 error "setstripe -S failed"
10117         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10118         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10119                 error "delete default stripe failed"
10120 }
10121 run_test 65g "directory setstripe -d"
10122
10123 test_65h() {
10124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10125
10126         test_mkdir $DIR/$tdir
10127         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10128
10129         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10130                 error "setstripe -S failed"
10131         test_mkdir $DIR/$tdir/dd1
10132         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10133                 error "stripe info inherit failed"
10134 }
10135 run_test 65h "directory stripe info inherit ===================="
10136
10137 test_65i() {
10138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10139
10140         save_layout_restore_at_exit $MOUNT
10141
10142         # bug6367: set non-default striping on root directory
10143         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10144
10145         # bug12836: getstripe on -1 default directory striping
10146         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10147
10148         # bug12836: getstripe -v on -1 default directory striping
10149         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10150
10151         # bug12836: new find on -1 default directory striping
10152         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10153 }
10154 run_test 65i "various tests to set root directory striping"
10155
10156 test_65j() { # bug6367
10157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10158
10159         sync; sleep 1
10160
10161         # if we aren't already remounting for each test, do so for this test
10162         if [ "$I_MOUNTED" = "yes" ]; then
10163                 cleanup || error "failed to unmount"
10164                 setup
10165         fi
10166
10167         save_layout_restore_at_exit $MOUNT
10168
10169         $LFS setstripe -d $MOUNT || error "setstripe failed"
10170 }
10171 run_test 65j "set default striping on root directory (bug 6367)="
10172
10173 cleanup_65k() {
10174         rm -rf $DIR/$tdir
10175         wait_delete_completed
10176         do_facet $SINGLEMDS "lctl set_param -n \
10177                 osp.$ost*MDT0000.max_create_count=$max_count"
10178         do_facet $SINGLEMDS "lctl set_param -n \
10179                 osp.$ost*MDT0000.create_count=$count"
10180         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10181         echo $INACTIVE_OSC "is Activate"
10182
10183         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10184 }
10185
10186 test_65k() { # bug11679
10187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10188         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10189         remote_mds_nodsh && skip "remote MDS with nodsh"
10190
10191         local disable_precreate=true
10192         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10193                 disable_precreate=false
10194
10195         echo "Check OST status: "
10196         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10197                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10198
10199         for OSC in $MDS_OSCS; do
10200                 echo $OSC "is active"
10201                 do_facet $SINGLEMDS lctl --device %$OSC activate
10202         done
10203
10204         for INACTIVE_OSC in $MDS_OSCS; do
10205                 local ost=$(osc_to_ost $INACTIVE_OSC)
10206                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10207                                lov.*md*.target_obd |
10208                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10209
10210                 mkdir -p $DIR/$tdir
10211                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10212                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10213
10214                 echo "Deactivate: " $INACTIVE_OSC
10215                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10216
10217                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10218                               osp.$ost*MDT0000.create_count")
10219                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10220                                   osp.$ost*MDT0000.max_create_count")
10221                 $disable_precreate &&
10222                         do_facet $SINGLEMDS "lctl set_param -n \
10223                                 osp.$ost*MDT0000.max_create_count=0"
10224
10225                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10226                         [ -f $DIR/$tdir/$idx ] && continue
10227                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10228                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10229                                 { cleanup_65k;
10230                                   error "setstripe $idx should succeed"; }
10231                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10232                 done
10233                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10234                 rmdir $DIR/$tdir
10235
10236                 do_facet $SINGLEMDS "lctl set_param -n \
10237                         osp.$ost*MDT0000.max_create_count=$max_count"
10238                 do_facet $SINGLEMDS "lctl set_param -n \
10239                         osp.$ost*MDT0000.create_count=$count"
10240                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10241                 echo $INACTIVE_OSC "is Activate"
10242
10243                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10244         done
10245 }
10246 run_test 65k "validate manual striping works properly with deactivated OSCs"
10247
10248 test_65l() { # bug 12836
10249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10250
10251         test_mkdir -p $DIR/$tdir/test_dir
10252         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10253         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10254 }
10255 run_test 65l "lfs find on -1 stripe dir ========================"
10256
10257 test_65m() {
10258         local layout=$(save_layout $MOUNT)
10259         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10260                 restore_layout $MOUNT $layout
10261                 error "setstripe should fail by non-root users"
10262         }
10263         true
10264 }
10265 run_test 65m "normal user can't set filesystem default stripe"
10266
10267 test_65n() {
10268         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10269         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10270                 skip "Need MDS version at least 2.12.50"
10271         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10272
10273         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10274         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10275         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10276
10277         save_layout_restore_at_exit $MOUNT
10278
10279         # new subdirectory under root directory should not inherit
10280         # the default layout from root
10281         # LU-16904 check if the root is set as PFL layout
10282         local numcomp=$($LFS getstripe --component-count $MOUNT)
10283
10284         if [[ $numcomp -eq 0 ]]; then
10285                 local dir1=$MOUNT/$tdir-1
10286                 mkdir $dir1 || error "mkdir $dir1 failed"
10287                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10288                         error "$dir1 shouldn't have LOV EA"
10289         fi
10290
10291         # delete the default layout on root directory
10292         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10293
10294         local dir2=$MOUNT/$tdir-2
10295         mkdir $dir2 || error "mkdir $dir2 failed"
10296         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10297                 error "$dir2 shouldn't have LOV EA"
10298
10299         # set a new striping pattern on root directory
10300         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10301         local new_def_stripe_size=$((def_stripe_size * 2))
10302         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10303                 error "set stripe size on $MOUNT failed"
10304
10305         # new file created in $dir2 should inherit the new stripe size from
10306         # the filesystem default
10307         local file2=$dir2/$tfile-2
10308         touch $file2 || error "touch $file2 failed"
10309
10310         local file2_stripe_size=$($LFS getstripe -S $file2)
10311         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10312         {
10313                 echo "file2_stripe_size: '$file2_stripe_size'"
10314                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10315                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10316         }
10317
10318         local dir3=$MOUNT/$tdir-3
10319         mkdir $dir3 || error "mkdir $dir3 failed"
10320         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10321         # the root layout, which is the actual default layout that will be used
10322         # when new files are created in $dir3.
10323         local dir3_layout=$(get_layout_param $dir3)
10324         local root_dir_layout=$(get_layout_param $MOUNT)
10325         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10326         {
10327                 echo "dir3_layout: '$dir3_layout'"
10328                 echo "root_dir_layout: '$root_dir_layout'"
10329                 error "$dir3 should show the default layout from $MOUNT"
10330         }
10331
10332         # set OST pool on root directory
10333         local pool=$TESTNAME
10334         pool_add $pool || error "add $pool failed"
10335         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10336                 error "add targets to $pool failed"
10337
10338         $LFS setstripe -p $pool $MOUNT ||
10339                 error "set OST pool on $MOUNT failed"
10340
10341         # new file created in $dir3 should inherit the pool from
10342         # the filesystem default
10343         local file3=$dir3/$tfile-3
10344         touch $file3 || error "touch $file3 failed"
10345
10346         local file3_pool=$($LFS getstripe -p $file3)
10347         [[ "$file3_pool" = "$pool" ]] ||
10348                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10349
10350         local dir4=$MOUNT/$tdir-4
10351         mkdir $dir4 || error "mkdir $dir4 failed"
10352         local dir4_layout=$(get_layout_param $dir4)
10353         root_dir_layout=$(get_layout_param $MOUNT)
10354         echo "$LFS getstripe -d $dir4"
10355         $LFS getstripe -d $dir4
10356         echo "$LFS getstripe -d $MOUNT"
10357         $LFS getstripe -d $MOUNT
10358         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10359         {
10360                 echo "dir4_layout: '$dir4_layout'"
10361                 echo "root_dir_layout: '$root_dir_layout'"
10362                 error "$dir4 should show the default layout from $MOUNT"
10363         }
10364
10365         # new file created in $dir4 should inherit the pool from
10366         # the filesystem default
10367         local file4=$dir4/$tfile-4
10368         touch $file4 || error "touch $file4 failed"
10369
10370         local file4_pool=$($LFS getstripe -p $file4)
10371         [[ "$file4_pool" = "$pool" ]] ||
10372                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10373
10374         # new subdirectory under non-root directory should inherit
10375         # the default layout from its parent directory
10376         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10377                 error "set directory layout on $dir4 failed"
10378
10379         local dir5=$dir4/$tdir-5
10380         mkdir $dir5 || error "mkdir $dir5 failed"
10381
10382         dir4_layout=$(get_layout_param $dir4)
10383         local dir5_layout=$(get_layout_param $dir5)
10384         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10385         {
10386                 echo "dir4_layout: '$dir4_layout'"
10387                 echo "dir5_layout: '$dir5_layout'"
10388                 error "$dir5 should inherit the default layout from $dir4"
10389         }
10390
10391         # though subdir under ROOT doesn't inherit default layout, but
10392         # its sub dir/file should be created with default layout.
10393         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10394         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10395                 skip "Need MDS version at least 2.12.59"
10396
10397         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10398         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10399         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10400
10401         if [ $default_lmv_hash == "none" ]; then
10402                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10403         else
10404                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10405                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10406         fi
10407
10408         $LFS setdirstripe -D -c 2 $MOUNT ||
10409                 error "setdirstripe -D -c 2 failed"
10410         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10411         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10412         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10413
10414         # $dir4 layout includes pool
10415         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10416         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10417                 error "pool lost on setstripe"
10418         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10419         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10420                 error "pool lost on compound layout setstripe"
10421 }
10422 run_test 65n "don't inherit default layout from root for new subdirectories"
10423
10424 test_65o() {
10425         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10426                 skip "need MDS version at least 2.14.57"
10427
10428         # set OST pool on root directory
10429         local pool=$TESTNAME
10430
10431         pool_add $pool || error "add $pool failed"
10432         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10433                 error "add targets to $pool failed"
10434
10435         local dir1=$MOUNT/$tdir
10436
10437         mkdir $dir1 || error "mkdir $dir1 failed"
10438
10439         # set a new striping pattern on root directory
10440         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10441
10442         $LFS setstripe -p $pool $dir1 ||
10443                 error "set directory layout on $dir1 failed"
10444
10445         # $dir1 layout includes pool
10446         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10447         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10448                 error "pool lost on setstripe"
10449         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10450         $LFS getstripe $dir1
10451         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10452                 error "pool lost on compound layout setstripe"
10453
10454         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10455                 error "setdirstripe failed on sub-dir with inherited pool"
10456         $LFS getstripe $dir1/dir2
10457         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10458                 error "pool lost on compound layout setdirstripe"
10459
10460         $LFS setstripe -E -1 -c 1 $dir1
10461         $LFS getstripe -d $dir1
10462         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10463                 error "pool lost on setstripe"
10464 }
10465 run_test 65o "pool inheritance for mdt component"
10466
10467 test_65p () { # LU-16152
10468         local src_dir=$DIR/$tdir/src_dir
10469         local dst_dir=$DIR/$tdir/dst_dir
10470         local yaml_file=$DIR/$tdir/layout.yaml
10471         local border
10472
10473         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10474                 skip "Need at least version 2.15.51"
10475
10476         test_mkdir -p $src_dir
10477         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10478                 error "failed to setstripe"
10479         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10480                 error "failed to getstripe"
10481
10482         test_mkdir -p $dst_dir
10483         $LFS setstripe --yaml $yaml_file $dst_dir ||
10484                 error "failed to setstripe with yaml file"
10485         border=$($LFS getstripe -d $dst_dir |
10486                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10487                 error "failed to getstripe"
10488
10489         # 2048M is 0x80000000, or 2147483648
10490         (( $border == 2147483648 )) ||
10491                 error "failed to handle huge number in yaml layout"
10492 }
10493 run_test 65p "setstripe with yaml file and huge number"
10494
10495 test_65q () { # LU-16194
10496         local src_dir=$DIR/$tdir/src_dir
10497
10498         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10499         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10500                 skip "Need at least version 2.15.51"
10501
10502         test_mkdir -p $src_dir
10503         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10504         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10505                 error "should fail if extent start/end >=8E"
10506
10507         # EOF should work as before
10508         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10509                 error "failed to setstripe normally"
10510 }
10511 run_test 65q "setstripe with >=8E offset should fail"
10512
10513 # bug 2543 - update blocks count on client
10514 test_66() {
10515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10516
10517         local COUNT=${COUNT:-8}
10518         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10519         sync; sync_all_data; sync; sync_all_data
10520         cancel_lru_locks osc
10521         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10522         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10523 }
10524 run_test 66 "update inode blocks count on client ==============="
10525
10526 meminfo() {
10527         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10528 }
10529
10530 swap_used() {
10531         swapon -s | awk '($1 == "'$1'") { print $4 }'
10532 }
10533
10534 # bug5265, obdfilter oa2dentry return -ENOENT
10535 # #define OBD_FAIL_SRV_ENOENT 0x217
10536 test_69() {
10537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10538         remote_ost_nodsh && skip "remote OST with nodsh"
10539
10540         f="$DIR/$tfile"
10541         $LFS setstripe -c 1 -i 0 $f
10542         stack_trap "rm -f $f ${f}.2"
10543
10544         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10545
10546         do_facet ost1 lctl set_param fail_loc=0x217
10547         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10548         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10549
10550         do_facet ost1 lctl set_param fail_loc=0
10551         $DIRECTIO write $f 0 2 || error "write error"
10552
10553         cancel_lru_locks osc
10554         $DIRECTIO read $f 0 1 || error "read error"
10555
10556         do_facet ost1 lctl set_param fail_loc=0x217
10557         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10558
10559         do_facet ost1 lctl set_param fail_loc=0
10560 }
10561 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10562
10563 test_70a() {
10564         # Perform a really simple test of health write and health check
10565         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10566                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10567
10568         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10569
10570         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10571
10572         # Test with health write off
10573         do_facet ost1 $LCTL set_param enable_health_write off ||
10574                 error "can't set enable_health_write off"
10575         do_facet ost1 $LCTL get_param enable_health_write ||
10576                 error "can't get enable_health_write"
10577
10578         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10579                 error "not healthy (1)"
10580
10581         # Test with health write on
10582         do_facet ost1 $LCTL set_param enable_health_write on ||
10583                 error "can't set enable_health_write on"
10584         do_facet ost1 $LCTL get_param enable_health_write ||
10585                 error "can't get enable_health_write"
10586
10587         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10588                 error "not healthy (2)"
10589 }
10590 run_test 70a "verify health_check, health_write don't explode (on OST)"
10591
10592 test_71() {
10593         test_mkdir $DIR/$tdir
10594         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10595         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10596 }
10597 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10598
10599 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10601         [ "$RUNAS_ID" = "$UID" ] &&
10602                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10603         # Check that testing environment is properly set up. Skip if not
10604         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10605                 skip_env "User $RUNAS_ID does not exist - skipping"
10606
10607         touch $DIR/$tfile
10608         chmod 777 $DIR/$tfile
10609         chmod ug+s $DIR/$tfile
10610         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10611                 error "$RUNAS dd $DIR/$tfile failed"
10612         # See if we are still setuid/sgid
10613         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10614                 error "S/gid is not dropped on write"
10615         # Now test that MDS is updated too
10616         cancel_lru_locks mdc
10617         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10618                 error "S/gid is not dropped on MDS"
10619         rm -f $DIR/$tfile
10620 }
10621 run_test 72a "Test that remove suid works properly (bug5695) ===="
10622
10623 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10624         local perm
10625
10626         [ "$RUNAS_ID" = "$UID" ] &&
10627                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10628         [ "$RUNAS_ID" -eq 0 ] &&
10629                 skip_env "RUNAS_ID = 0 -- skipping"
10630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10631         # Check that testing environment is properly set up. Skip if not
10632         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10633                 skip_env "User $RUNAS_ID does not exist - skipping"
10634
10635         touch $DIR/${tfile}-f{g,u}
10636         test_mkdir $DIR/${tfile}-dg
10637         test_mkdir $DIR/${tfile}-du
10638         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10639         chmod g+s $DIR/${tfile}-{f,d}g
10640         chmod u+s $DIR/${tfile}-{f,d}u
10641         for perm in 777 2777 4777; do
10642                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10643                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10644                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10645                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10646         done
10647         true
10648 }
10649 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10650
10651 # bug 3462 - multiple simultaneous MDC requests
10652 test_73() {
10653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10654
10655         test_mkdir $DIR/d73-1
10656         test_mkdir $DIR/d73-2
10657         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10658         pid1=$!
10659
10660         lctl set_param fail_loc=0x80000129
10661         $MULTIOP $DIR/d73-1/f73-2 Oc &
10662         sleep 1
10663         lctl set_param fail_loc=0
10664
10665         $MULTIOP $DIR/d73-2/f73-3 Oc &
10666         pid3=$!
10667
10668         kill -USR1 $pid1
10669         wait $pid1 || return 1
10670
10671         sleep 25
10672
10673         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10674         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10675         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10676
10677         rm -rf $DIR/d73-*
10678 }
10679 run_test 73 "multiple MDC requests (should not deadlock)"
10680
10681 test_74a() { # bug 6149, 6184
10682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10683
10684         touch $DIR/f74a
10685         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10686         #
10687         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10688         # will spin in a tight reconnection loop
10689         $LCTL set_param fail_loc=0x8000030e
10690         # get any lock that won't be difficult - lookup works.
10691         ls $DIR/f74a
10692         $LCTL set_param fail_loc=0
10693         rm -f $DIR/f74a
10694         true
10695 }
10696 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10697
10698 test_74b() { # bug 13310
10699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10700
10701         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10702         #
10703         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10704         # will spin in a tight reconnection loop
10705         $LCTL set_param fail_loc=0x8000030e
10706         # get a "difficult" lock
10707         touch $DIR/f74b
10708         $LCTL set_param fail_loc=0
10709         rm -f $DIR/f74b
10710         true
10711 }
10712 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10713
10714 test_74c() {
10715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10716
10717         #define OBD_FAIL_LDLM_NEW_LOCK
10718         $LCTL set_param fail_loc=0x319
10719         touch $DIR/$tfile && error "touch successful"
10720         $LCTL set_param fail_loc=0
10721         true
10722 }
10723 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10724
10725 slab_lic=/sys/kernel/slab/lustre_inode_cache
10726 num_objects() {
10727         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10728         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10729                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10730 }
10731
10732 test_76a() { # Now for b=20433, added originally in b=1443
10733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10734
10735         cancel_lru_locks osc
10736         # there may be some slab objects cached per core
10737         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10738         local before=$(num_objects)
10739         local count=$((512 * cpus))
10740         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10741         local margin=$((count / 10))
10742         if [[ -f $slab_lic/aliases ]]; then
10743                 local aliases=$(cat $slab_lic/aliases)
10744                 (( aliases > 0 )) && margin=$((margin * aliases))
10745         fi
10746
10747         echo "before slab objects: $before"
10748         for i in $(seq $count); do
10749                 touch $DIR/$tfile
10750                 rm -f $DIR/$tfile
10751         done
10752         cancel_lru_locks osc
10753         local after=$(num_objects)
10754         echo "created: $count, after slab objects: $after"
10755         # shared slab counts are not very accurate, allow significant margin
10756         # the main goal is that the cache growth is not permanently > $count
10757         while (( after > before + margin )); do
10758                 sleep 1
10759                 after=$(num_objects)
10760                 wait=$((wait + 1))
10761                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10762                 if (( wait > 60 )); then
10763                         error "inode slab grew from $before+$margin to $after"
10764                 fi
10765         done
10766 }
10767 run_test 76a "confirm clients recycle inodes properly ===="
10768
10769 test_76b() {
10770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10771         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10772
10773         local count=512
10774         local before=$(num_objects)
10775
10776         for i in $(seq $count); do
10777                 mkdir $DIR/$tdir
10778                 rmdir $DIR/$tdir
10779         done
10780
10781         local after=$(num_objects)
10782         local wait=0
10783
10784         while (( after > before )); do
10785                 sleep 1
10786                 after=$(num_objects)
10787                 wait=$((wait + 1))
10788                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10789                 if (( wait > 60 )); then
10790                         error "inode slab grew from $before to $after"
10791                 fi
10792         done
10793
10794         echo "slab objects before: $before, after: $after"
10795 }
10796 run_test 76b "confirm clients recycle directory inodes properly ===="
10797
10798 export ORIG_CSUM=""
10799 set_checksums()
10800 {
10801         # Note: in sptlrpc modes which enable its own bulk checksum, the
10802         # original crc32_le bulk checksum will be automatically disabled,
10803         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10804         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10805         # In this case set_checksums() will not be no-op, because sptlrpc
10806         # bulk checksum will be enabled all through the test.
10807
10808         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10809         lctl set_param -n osc.*.checksums $1
10810         return 0
10811 }
10812
10813 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10814                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10815 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10816                              tr -d [] | head -n1)}
10817 set_checksum_type()
10818 {
10819         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10820         rc=$?
10821         log "set checksum type to $1, rc = $rc"
10822         return $rc
10823 }
10824
10825 get_osc_checksum_type()
10826 {
10827         # arugment 1: OST name, like OST0000
10828         ost=$1
10829         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10830                         sed 's/.*\[\(.*\)\].*/\1/g')
10831         rc=$?
10832         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10833         echo $checksum_type
10834 }
10835
10836 F77_TMP=$TMP/f77-temp
10837 F77SZ=8
10838 setup_f77() {
10839         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10840                 error "error writing to $F77_TMP"
10841 }
10842
10843 test_77a() { # bug 10889
10844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10845         $GSS && skip_env "could not run with gss"
10846
10847         [ ! -f $F77_TMP ] && setup_f77
10848         set_checksums 1
10849         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10850         set_checksums 0
10851         rm -f $DIR/$tfile
10852 }
10853 run_test 77a "normal checksum read/write operation"
10854
10855 test_77b() { # bug 10889
10856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10857         $GSS && skip_env "could not run with gss"
10858
10859         [ ! -f $F77_TMP ] && setup_f77
10860         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10861         $LCTL set_param fail_loc=0x80000409
10862         set_checksums 1
10863
10864         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10865                 error "dd error: $?"
10866         $LCTL set_param fail_loc=0
10867
10868         for algo in $CKSUM_TYPES; do
10869                 cancel_lru_locks osc
10870                 set_checksum_type $algo
10871                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10872                 $LCTL set_param fail_loc=0x80000408
10873                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10874                 $LCTL set_param fail_loc=0
10875         done
10876         set_checksums 0
10877         set_checksum_type $ORIG_CSUM_TYPE
10878         rm -f $DIR/$tfile
10879 }
10880 run_test 77b "checksum error on client write, read"
10881
10882 cleanup_77c() {
10883         trap 0
10884         set_checksums 0
10885         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10886         $check_ost &&
10887                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10888         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10889         $check_ost && [ -n "$ost_file_prefix" ] &&
10890                 do_facet ost1 rm -f ${ost_file_prefix}\*
10891 }
10892
10893 test_77c() {
10894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10895         $GSS && skip_env "could not run with gss"
10896         remote_ost_nodsh && skip "remote OST with nodsh"
10897
10898         local bad1
10899         local osc_file_prefix
10900         local osc_file
10901         local check_ost=false
10902         local ost_file_prefix
10903         local ost_file
10904         local orig_cksum
10905         local dump_cksum
10906         local fid
10907
10908         # ensure corruption will occur on first OSS/OST
10909         $LFS setstripe -i 0 $DIR/$tfile
10910
10911         [ ! -f $F77_TMP ] && setup_f77
10912         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10913                 error "dd write error: $?"
10914         fid=$($LFS path2fid $DIR/$tfile)
10915
10916         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10917         then
10918                 check_ost=true
10919                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10920                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10921         else
10922                 echo "OSS do not support bulk pages dump upon error"
10923         fi
10924
10925         osc_file_prefix=$($LCTL get_param -n debug_path)
10926         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10927
10928         trap cleanup_77c EXIT
10929
10930         set_checksums 1
10931         # enable bulk pages dump upon error on Client
10932         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10933         # enable bulk pages dump upon error on OSS
10934         $check_ost &&
10935                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10936
10937         # flush Client cache to allow next read to reach OSS
10938         cancel_lru_locks osc
10939
10940         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10941         $LCTL set_param fail_loc=0x80000408
10942         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10943         $LCTL set_param fail_loc=0
10944
10945         rm -f $DIR/$tfile
10946
10947         # check cksum dump on Client
10948         osc_file=$(ls ${osc_file_prefix}*)
10949         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10950         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10951         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10952         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10953         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10954                      cksum)
10955         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10956         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10957                 error "dump content does not match on Client"
10958
10959         $check_ost || skip "No need to check cksum dump on OSS"
10960
10961         # check cksum dump on OSS
10962         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10963         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10964         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10965         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10966         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10967                 error "dump content does not match on OSS"
10968
10969         cleanup_77c
10970 }
10971 run_test 77c "checksum error on client read with debug"
10972
10973 test_77d() { # bug 10889
10974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10975         $GSS && skip_env "could not run with gss"
10976
10977         stack_trap "rm -f $DIR/$tfile"
10978         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10979         $LCTL set_param fail_loc=0x80000409
10980         set_checksums 1
10981         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10982                 error "direct write: rc=$?"
10983         $LCTL set_param fail_loc=0
10984         set_checksums 0
10985
10986         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10987         $LCTL set_param fail_loc=0x80000408
10988         set_checksums 1
10989         cancel_lru_locks osc
10990         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10991                 error "direct read: rc=$?"
10992         $LCTL set_param fail_loc=0
10993         set_checksums 0
10994 }
10995 run_test 77d "checksum error on OST direct write, read"
10996
10997 test_77f() { # bug 10889
10998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10999         $GSS && skip_env "could not run with gss"
11000
11001         set_checksums 1
11002         stack_trap "rm -f $DIR/$tfile"
11003         for algo in $CKSUM_TYPES; do
11004                 cancel_lru_locks osc
11005                 set_checksum_type $algo
11006                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11007                 $LCTL set_param fail_loc=0x409
11008                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11009                         error "direct write succeeded"
11010                 $LCTL set_param fail_loc=0
11011         done
11012         set_checksum_type $ORIG_CSUM_TYPE
11013         set_checksums 0
11014 }
11015 run_test 77f "repeat checksum error on write (expect error)"
11016
11017 test_77g() { # bug 10889
11018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11019         $GSS && skip_env "could not run with gss"
11020         remote_ost_nodsh && skip "remote OST with nodsh"
11021
11022         [ ! -f $F77_TMP ] && setup_f77
11023
11024         local file=$DIR/$tfile
11025         stack_trap "rm -f $file" EXIT
11026
11027         $LFS setstripe -c 1 -i 0 $file
11028         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11029         do_facet ost1 lctl set_param fail_loc=0x8000021a
11030         set_checksums 1
11031         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11032                 error "write error: rc=$?"
11033         do_facet ost1 lctl set_param fail_loc=0
11034         set_checksums 0
11035
11036         cancel_lru_locks osc
11037         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11038         do_facet ost1 lctl set_param fail_loc=0x8000021b
11039         set_checksums 1
11040         cmp $F77_TMP $file || error "file compare failed"
11041         do_facet ost1 lctl set_param fail_loc=0
11042         set_checksums 0
11043 }
11044 run_test 77g "checksum error on OST write, read"
11045
11046 test_77k() { # LU-10906
11047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11048         $GSS && skip_env "could not run with gss"
11049
11050         local cksum_param="osc.$FSNAME*.checksums"
11051         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11052         local checksum
11053         local i
11054
11055         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11056         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11057         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11058
11059         for i in 0 1; do
11060                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11061                         error "failed to set checksum=$i on MGS"
11062                 wait_update $HOSTNAME "$get_checksum" $i
11063                 #remount
11064                 echo "remount client, checksum should be $i"
11065                 remount_client $MOUNT || error "failed to remount client"
11066                 checksum=$(eval $get_checksum)
11067                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11068         done
11069         # remove persistent param to avoid races with checksum mountopt below
11070         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11071                 error "failed to delete checksum on MGS"
11072
11073         for opt in "checksum" "nochecksum"; do
11074                 #remount with mount option
11075                 echo "remount client with option $opt, checksum should be $i"
11076                 umount_client $MOUNT || error "failed to umount client"
11077                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11078                         error "failed to mount client with option '$opt'"
11079                 checksum=$(eval $get_checksum)
11080                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11081                 i=$((i - 1))
11082         done
11083
11084         remount_client $MOUNT || error "failed to remount client"
11085 }
11086 run_test 77k "enable/disable checksum correctly"
11087
11088 test_77l() {
11089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11090         $GSS && skip_env "could not run with gss"
11091
11092         set_checksums 1
11093         stack_trap "set_checksums $ORIG_CSUM" EXIT
11094         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11095         local old
11096
11097         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11098         $LCTL set_param osc.*.idle_timeout=10
11099         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11100
11101         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11102
11103         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11104         for algo in $CKSUM_TYPES; do
11105                 set_checksum_type $algo || error "fail to set checksum type $algo"
11106                 osc_algo=$(get_osc_checksum_type OST0000)
11107                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11108
11109                 # no locks, no reqs to let the connection idle
11110                 cancel_lru_locks osc
11111                 lru_resize_disable osc
11112                 wait_osc_import_state client ost1 IDLE
11113
11114                 # ensure ost1 is connected
11115                 stat $DIR/$tfile >/dev/null || error "can't stat"
11116                 wait_osc_import_state client ost1 FULL
11117
11118                 osc_algo=$(get_osc_checksum_type OST0000)
11119                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11120         done
11121         return 0
11122 }
11123 run_test 77l "preferred checksum type is remembered after reconnected"
11124
11125 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11126 rm -f $F77_TMP
11127 unset F77_TMP
11128
11129 test_77m() {
11130         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11131                 skip "Need at least version 2.14.52"
11132         local param=checksum_speed
11133
11134         $LCTL get_param $param || error "reading $param failed"
11135
11136         csum_speeds=$($LCTL get_param -n $param)
11137
11138         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11139                 error "known checksum types are missing"
11140 }
11141 run_test 77m "Verify checksum_speed is correctly read"
11142
11143 check_filefrag_77n() {
11144         local nr_ext=0
11145         local starts=()
11146         local ends=()
11147
11148         while read extidx a b start end rest; do
11149                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11150                         nr_ext=$(( $nr_ext + 1 ))
11151                         starts+=( ${start%..} )
11152                         ends+=( ${end%:} )
11153                 fi
11154         done < <( filefrag -sv $1 )
11155
11156         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11157         return 1
11158 }
11159
11160 test_77n() {
11161         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11162
11163         touch $DIR/$tfile
11164         $TRUNCATE $DIR/$tfile 0
11165         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11166         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11167         check_filefrag_77n $DIR/$tfile ||
11168                 skip "$tfile blocks not contiguous around hole"
11169
11170         set_checksums 1
11171         stack_trap "set_checksums $ORIG_CSUM" EXIT
11172         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11173         stack_trap "rm -f $DIR/$tfile"
11174
11175         for algo in $CKSUM_TYPES; do
11176                 if [[ "$algo" =~ ^t10 ]]; then
11177                         set_checksum_type $algo ||
11178                                 error "fail to set checksum type $algo"
11179                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11180                                 error "fail to read $tfile with $algo"
11181                 fi
11182         done
11183         rm -f $DIR/$tfile
11184         return 0
11185 }
11186 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11187
11188 test_77o() {
11189         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11190                 skip "Need MDS version at least 2.14.55"
11191         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11192                 skip "Need OST version at least 2.14.55"
11193         local ofd=obdfilter
11194         local mdt=mdt
11195
11196         # print OST checksum_type
11197         echo "$ofd.$FSNAME-*.checksum_type:"
11198         do_nodes $(comma_list $(osts_nodes)) \
11199                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11200
11201         # print MDT checksum_type
11202         echo "$mdt.$FSNAME-*.checksum_type:"
11203         do_nodes $(comma_list $(mdts_nodes)) \
11204                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11205
11206         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11207                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11208
11209         (( $o_count == $OSTCOUNT )) ||
11210                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11211
11212         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11213                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11214
11215         (( $m_count == $MDSCOUNT )) ||
11216                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11217 }
11218 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11219
11220 cleanup_test_78() {
11221         trap 0
11222         rm -f $DIR/$tfile
11223 }
11224
11225 test_78() { # bug 10901
11226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11227         remote_ost || skip_env "local OST"
11228
11229         NSEQ=5
11230         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11231         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11232         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11233         echo "MemTotal: $MEMTOTAL"
11234
11235         # reserve 256MB of memory for the kernel and other running processes,
11236         # and then take 1/2 of the remaining memory for the read/write buffers.
11237         if [ $MEMTOTAL -gt 512 ] ;then
11238                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11239         else
11240                 # for those poor memory-starved high-end clusters...
11241                 MEMTOTAL=$((MEMTOTAL / 2))
11242         fi
11243         echo "Mem to use for directio: $MEMTOTAL"
11244
11245         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11246         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11247         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11248         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11249                 head -n1)
11250         echo "Smallest OST: $SMALLESTOST"
11251         [[ $SMALLESTOST -lt 10240 ]] &&
11252                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11253
11254         trap cleanup_test_78 EXIT
11255
11256         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11257                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11258
11259         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11260         echo "File size: $F78SIZE"
11261         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11262         for i in $(seq 1 $NSEQ); do
11263                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11264                 echo directIO rdwr round $i of $NSEQ
11265                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11266         done
11267
11268         cleanup_test_78
11269 }
11270 run_test 78 "handle large O_DIRECT writes correctly ============"
11271
11272 test_79() { # bug 12743
11273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11274
11275         wait_delete_completed
11276
11277         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11278         BKFREE=$(calc_osc_kbytes kbytesfree)
11279         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11280
11281         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11282         DFTOTAL=`echo $STRING | cut -d, -f1`
11283         DFUSED=`echo $STRING  | cut -d, -f2`
11284         DFAVAIL=`echo $STRING | cut -d, -f3`
11285         DFFREE=$(($DFTOTAL - $DFUSED))
11286
11287         ALLOWANCE=$((64 * $OSTCOUNT))
11288
11289         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11290            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11291                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11292         fi
11293         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11294            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11295                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11296         fi
11297         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11298            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11299                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11300         fi
11301 }
11302 run_test 79 "df report consistency check ======================="
11303
11304 test_80() { # bug 10718
11305         remote_ost_nodsh && skip "remote OST with nodsh"
11306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11307
11308         # relax strong synchronous semantics for slow backends like ZFS
11309         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11310                 local soc="obdfilter.*.sync_lock_cancel"
11311                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11312
11313                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11314                 if [ -z "$save" ]; then
11315                         soc="obdfilter.*.sync_on_lock_cancel"
11316                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11317                 fi
11318
11319                 if [ "$save" != "never" ]; then
11320                         local hosts=$(comma_list $(osts_nodes))
11321
11322                         do_nodes $hosts $LCTL set_param $soc=never
11323                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11324                 fi
11325         fi
11326
11327         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11328         sync; sleep 1; sync
11329         local before=$(date +%s)
11330         cancel_lru_locks osc
11331         local after=$(date +%s)
11332         local diff=$((after - before))
11333         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11334
11335         rm -f $DIR/$tfile
11336 }
11337 run_test 80 "Page eviction is equally fast at high offsets too"
11338
11339 test_81a() { # LU-456
11340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11341         remote_ost_nodsh && skip "remote OST with nodsh"
11342
11343         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11344         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11345         do_facet ost1 lctl set_param fail_loc=0x80000228
11346
11347         # write should trigger a retry and success
11348         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11349         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11350         RC=$?
11351         if [ $RC -ne 0 ] ; then
11352                 error "write should success, but failed for $RC"
11353         fi
11354 }
11355 run_test 81a "OST should retry write when get -ENOSPC ==============="
11356
11357 test_81b() { # LU-456
11358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11359         remote_ost_nodsh && skip "remote OST with nodsh"
11360
11361         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11362         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11363         do_facet ost1 lctl set_param fail_loc=0x228
11364
11365         # write should retry several times and return -ENOSPC finally
11366         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11367         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11368         RC=$?
11369         ENOSPC=28
11370         if [ $RC -ne $ENOSPC ] ; then
11371                 error "dd should fail for -ENOSPC, but succeed."
11372         fi
11373 }
11374 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11375
11376 test_99() {
11377         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11378
11379         test_mkdir $DIR/$tdir.cvsroot
11380         chown $RUNAS_ID $DIR/$tdir.cvsroot
11381
11382         cd $TMP
11383         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11384
11385         cd /etc/init.d
11386         # some versions of cvs import exit(1) when asked to import links or
11387         # files they can't read.  ignore those files.
11388         local toignore=$(find . -type l -printf '-I %f\n' -o \
11389                          ! -perm /4 -printf '-I %f\n')
11390         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11391                 $tdir.reposname vtag rtag
11392
11393         cd $DIR
11394         test_mkdir $DIR/$tdir.reposname
11395         chown $RUNAS_ID $DIR/$tdir.reposname
11396         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11397
11398         cd $DIR/$tdir.reposname
11399         $RUNAS touch foo99
11400         $RUNAS cvs add -m 'addmsg' foo99
11401         $RUNAS cvs update
11402         $RUNAS cvs commit -m 'nomsg' foo99
11403         rm -fr $DIR/$tdir.cvsroot
11404 }
11405 run_test 99 "cvs strange file/directory operations"
11406
11407 test_100() {
11408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11409         [[ "$NETTYPE" =~ tcp ]] ||
11410                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11411         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11412         remote_ost_nodsh && skip "remote OST with nodsh"
11413         remote_mds_nodsh && skip "remote MDS with nodsh"
11414         remote_servers || skip "useless for local single node setup"
11415
11416         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11417                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11418
11419                 rc=0
11420                 if (( ${LOCAL/*:/} >= 1024 )); then
11421                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11422                         ss -tna
11423                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11424                 fi
11425         done
11426         (( $rc == 0 )) || error "privileged port not found" )
11427 }
11428 run_test 100 "check local port using privileged port"
11429
11430 function get_named_value()
11431 {
11432     local tag=$1
11433
11434     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11435 }
11436
11437 test_101a() {
11438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11439
11440         local s
11441         local discard
11442         local nreads=10000
11443         local cache_limit=32
11444
11445         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11446         $LCTL set_param -n llite.*.read_ahead_stats=0
11447         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11448                               awk '/^max_cached_mb/ { print $2 }')
11449         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11450         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11451
11452         #
11453         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11454         #
11455         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11456         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11457
11458         discard=0
11459         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11460                    get_named_value 'read.but.discarded'); do
11461                         discard=$(($discard + $s))
11462         done
11463
11464         $LCTL get_param osc.*-osc*.rpc_stats
11465         $LCTL get_param llite.*.read_ahead_stats
11466
11467         # Discard is generally zero, but sometimes a few random reads line up
11468         # and trigger larger readahead, which is wasted & leads to discards.
11469         if [[ $(($discard)) -gt $nreads ]]; then
11470                 error "too many ($discard) discarded pages"
11471         fi
11472         rm -f $DIR/$tfile || true
11473 }
11474 run_test 101a "check read-ahead for random reads"
11475
11476 setup_test101bc() {
11477         test_mkdir $DIR/$tdir
11478         local ssize=$1
11479         local FILE_LENGTH=$2
11480         STRIPE_OFFSET=0
11481
11482         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11483
11484         local list=$(comma_list $(osts_nodes))
11485         set_osd_param $list '' read_cache_enable 0
11486         set_osd_param $list '' writethrough_cache_enable 0
11487
11488         trap cleanup_test101bc EXIT
11489         # prepare the read-ahead file
11490         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11491
11492         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11493                                 count=$FILE_SIZE_MB 2> /dev/null
11494
11495 }
11496
11497 cleanup_test101bc() {
11498         trap 0
11499         rm -rf $DIR/$tdir
11500         rm -f $DIR/$tfile
11501
11502         local list=$(comma_list $(osts_nodes))
11503         set_osd_param $list '' read_cache_enable 1
11504         set_osd_param $list '' writethrough_cache_enable 1
11505 }
11506
11507 ra_check_101() {
11508         local read_size=$1
11509         local stripe_size=$2
11510         local stride_length=$((stripe_size / read_size))
11511         local stride_width=$((stride_length * OSTCOUNT))
11512         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11513                                 (stride_width - stride_length) ))
11514         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11515                   get_named_value 'read.but.discarded' | calc_sum)
11516
11517         if [[ $discard -gt $discard_limit ]]; then
11518                 $LCTL get_param llite.*.read_ahead_stats
11519                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11520         else
11521                 echo "Read-ahead success for size ${read_size}"
11522         fi
11523 }
11524
11525 test_101b() {
11526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11528
11529         local STRIPE_SIZE=1048576
11530         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11531
11532         if [ $SLOW == "yes" ]; then
11533                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11534         else
11535                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11536         fi
11537
11538         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11539
11540         # prepare the read-ahead file
11541         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11542         cancel_lru_locks osc
11543         for BIDX in 2 4 8 16 32 64 128 256
11544         do
11545                 local BSIZE=$((BIDX*4096))
11546                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11547                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11548                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11549                 $LCTL set_param -n llite.*.read_ahead_stats=0
11550                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11551                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11552                 cancel_lru_locks osc
11553                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11554         done
11555         cleanup_test101bc
11556         true
11557 }
11558 run_test 101b "check stride-io mode read-ahead ================="
11559
11560 test_101c() {
11561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11562
11563         local STRIPE_SIZE=1048576
11564         local FILE_LENGTH=$((STRIPE_SIZE*100))
11565         local nreads=10000
11566         local rsize=65536
11567         local osc_rpc_stats
11568
11569         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11570
11571         cancel_lru_locks osc
11572         $LCTL set_param osc.*.rpc_stats=0
11573         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11574         $LCTL get_param osc.*.rpc_stats
11575         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11576                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11577                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11578                 local size
11579
11580                 if [ $lines -le 20 ]; then
11581                         echo "continue debug"
11582                         continue
11583                 fi
11584                 for size in 1 2 4 8; do
11585                         local rpc=$(echo "$stats" |
11586                                     awk '($1 == "'$size':") {print $2; exit; }')
11587                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11588                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11589                 done
11590                 echo "$osc_rpc_stats check passed!"
11591         done
11592         cleanup_test101bc
11593         true
11594 }
11595 run_test 101c "check stripe_size aligned read-ahead"
11596
11597 test_101d() {
11598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11599
11600         local file=$DIR/$tfile
11601         local sz_MB=${FILESIZE_101d:-80}
11602         local ra_MB=${READAHEAD_MB:-40}
11603
11604         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11605         [ $free_MB -lt $sz_MB ] &&
11606                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11607
11608         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11609         $LFS setstripe -c -1 $file || error "setstripe failed"
11610
11611         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11612         echo Cancel LRU locks on lustre client to flush the client cache
11613         cancel_lru_locks osc
11614
11615         echo Disable read-ahead
11616         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11617         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11618         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11619         $LCTL get_param -n llite.*.max_read_ahead_mb
11620
11621         echo "Reading the test file $file with read-ahead disabled"
11622         local sz_KB=$((sz_MB * 1024 / 4))
11623         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11624         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11625         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11626         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11627                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11628
11629         echo "Cancel LRU locks on lustre client to flush the client cache"
11630         cancel_lru_locks osc
11631         echo Enable read-ahead with ${ra_MB}MB
11632         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11633
11634         echo "Reading the test file $file with read-ahead enabled"
11635         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11636                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11637
11638         echo "read-ahead disabled time read '$raOFF'"
11639         echo "read-ahead enabled time read '$raON'"
11640
11641         rm -f $file
11642         wait_delete_completed
11643
11644         # use awk for this check instead of bash because it handles decimals
11645         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11646                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11647 }
11648 run_test 101d "file read with and without read-ahead enabled"
11649
11650 test_101e() {
11651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11652
11653         local file=$DIR/$tfile
11654         local size_KB=500  #KB
11655         local count=100
11656         local bsize=1024
11657
11658         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11659         local need_KB=$((count * size_KB))
11660         [[ $free_KB -le $need_KB ]] &&
11661                 skip_env "Need free space $need_KB, have $free_KB"
11662
11663         echo "Creating $count ${size_KB}K test files"
11664         for ((i = 0; i < $count; i++)); do
11665                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11666         done
11667
11668         echo "Cancel LRU locks on lustre client to flush the client cache"
11669         cancel_lru_locks $OSC
11670
11671         echo "Reset readahead stats"
11672         $LCTL set_param -n llite.*.read_ahead_stats=0
11673
11674         for ((i = 0; i < $count; i++)); do
11675                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11676         done
11677
11678         $LCTL get_param llite.*.max_cached_mb
11679         $LCTL get_param llite.*.read_ahead_stats
11680         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11681                      get_named_value 'misses' | calc_sum)
11682
11683         for ((i = 0; i < $count; i++)); do
11684                 rm -rf $file.$i 2>/dev/null
11685         done
11686
11687         #10000 means 20% reads are missing in readahead
11688         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11689 }
11690 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11691
11692 test_101f() {
11693         which iozone || skip_env "no iozone installed"
11694
11695         local old_debug=$($LCTL get_param debug)
11696         old_debug=${old_debug#*=}
11697         $LCTL set_param debug="reada mmap"
11698
11699         # create a test file
11700         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11701
11702         echo Cancel LRU locks on lustre client to flush the client cache
11703         cancel_lru_locks osc
11704
11705         echo Reset readahead stats
11706         $LCTL set_param -n llite.*.read_ahead_stats=0
11707
11708         echo mmap read the file with small block size
11709         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11710                 > /dev/null 2>&1
11711
11712         echo checking missing pages
11713         $LCTL get_param llite.*.read_ahead_stats
11714         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11715                         get_named_value 'misses' | calc_sum)
11716
11717         $LCTL set_param debug="$old_debug"
11718         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11719         rm -f $DIR/$tfile
11720 }
11721 run_test 101f "check mmap read performance"
11722
11723 test_101g_brw_size_test() {
11724         local mb=$1
11725         local pages=$((mb * 1048576 / PAGE_SIZE))
11726         local file=$DIR/$tfile
11727
11728         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11729                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11730         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11731                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11732                         return 2
11733         done
11734
11735         stack_trap "rm -f $file" EXIT
11736         $LCTL set_param -n osc.*.rpc_stats=0
11737
11738         # 10 RPCs should be enough for the test
11739         local count=10
11740         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11741                 { error "dd write ${mb} MB blocks failed"; return 3; }
11742         cancel_lru_locks osc
11743         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11744                 { error "dd write ${mb} MB blocks failed"; return 4; }
11745
11746         # calculate number of full-sized read and write RPCs
11747         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11748                 sed -n '/pages per rpc/,/^$/p' |
11749                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11750                 END { print reads,writes }'))
11751         # allow one extra full-sized read RPC for async readahead
11752         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11753                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11754         [[ ${rpcs[1]} == $count ]] ||
11755                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11756 }
11757
11758 test_101g() {
11759         remote_ost_nodsh && skip "remote OST with nodsh"
11760
11761         local rpcs
11762         local osts=$(get_facets OST)
11763         local list=$(comma_list $(osts_nodes))
11764         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11765         local brw_size="obdfilter.*.brw_size"
11766
11767         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11768
11769         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11770
11771         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11772                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11773                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11774            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11775                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11776                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11777
11778                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11779                         suffix="M"
11780
11781                 if [[ $orig_mb -lt 16 ]]; then
11782                         save_lustre_params $osts "$brw_size" > $p
11783                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11784                                 error "set 16MB RPC size failed"
11785
11786                         echo "remount client to enable new RPC size"
11787                         remount_client $MOUNT || error "remount_client failed"
11788                 fi
11789
11790                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11791                 # should be able to set brw_size=12, but no rpc_stats for that
11792                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11793         fi
11794
11795         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11796
11797         if [[ $orig_mb -lt 16 ]]; then
11798                 restore_lustre_params < $p
11799                 remount_client $MOUNT || error "remount_client restore failed"
11800         fi
11801
11802         rm -f $p $DIR/$tfile
11803 }
11804 run_test 101g "Big bulk(4/16 MiB) readahead"
11805
11806 test_101h() {
11807         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11808
11809         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11810                 error "dd 70M file failed"
11811         echo Cancel LRU locks on lustre client to flush the client cache
11812         cancel_lru_locks osc
11813
11814         echo "Reset readahead stats"
11815         $LCTL set_param -n llite.*.read_ahead_stats 0
11816
11817         echo "Read 10M of data but cross 64M bundary"
11818         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11819         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11820                      get_named_value 'misses' | calc_sum)
11821         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11822         rm -f $p $DIR/$tfile
11823 }
11824 run_test 101h "Readahead should cover current read window"
11825
11826 test_101i() {
11827         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11828                 error "dd 10M file failed"
11829
11830         local max_per_file_mb=$($LCTL get_param -n \
11831                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11832         cancel_lru_locks osc
11833         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11834         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11835                 error "set max_read_ahead_per_file_mb to 1 failed"
11836
11837         echo "Reset readahead stats"
11838         $LCTL set_param llite.*.read_ahead_stats=0
11839
11840         dd if=$DIR/$tfile of=/dev/null bs=2M
11841
11842         $LCTL get_param llite.*.read_ahead_stats
11843         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11844                      awk '/misses/ { print $2 }')
11845         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11846         rm -f $DIR/$tfile
11847 }
11848 run_test 101i "allow current readahead to exceed reservation"
11849
11850 test_101j() {
11851         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11852                 error "setstripe $DIR/$tfile failed"
11853         local file_size=$((1048576 * 16))
11854         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11855         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11856
11857         echo Disable read-ahead
11858         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11859
11860         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11861         for blk in $PAGE_SIZE 1048576 $file_size; do
11862                 cancel_lru_locks osc
11863                 echo "Reset readahead stats"
11864                 $LCTL set_param -n llite.*.read_ahead_stats=0
11865                 local count=$(($file_size / $blk))
11866                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11867                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11868                              get_named_value 'failed.to.fast.read' | calc_sum)
11869                 $LCTL get_param -n llite.*.read_ahead_stats
11870                 [ $miss -eq $count ] || error "expected $count got $miss"
11871         done
11872
11873         rm -f $p $DIR/$tfile
11874 }
11875 run_test 101j "A complete read block should be submitted when no RA"
11876
11877 test_readahead_base() {
11878         local file=$DIR/$tfile
11879         local size=$1
11880         local iosz
11881         local ramax
11882         local ranum
11883
11884         $LCTL set_param -n llite.*.read_ahead_stats=0
11885         # The first page is not accounted into readahead
11886         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11887         iosz=$(((size + 1048575) / 1048576 * 1048576))
11888         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11889
11890         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11891         fallocate -l $size $file || error "failed to fallocate $file"
11892         cancel_lru_locks osc
11893         $MULTIOP $file or${iosz}c || error "failed to read $file"
11894         $LCTL get_param -n llite.*.read_ahead_stats
11895         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11896                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11897         (( $ranum <= $ramax )) ||
11898                 error "read-ahead pages is $ranum more than $ramax"
11899         rm -rf $file || error "failed to remove $file"
11900 }
11901
11902 test_101m()
11903 {
11904         local file=$DIR/$tfile
11905         local ramax
11906         local ranum
11907         local size
11908         local iosz
11909
11910         check_set_fallocate_or_skip
11911         stack_trap "rm -f $file" EXIT
11912
11913         test_readahead_base 4096
11914
11915         # file size: 16K = 16384
11916         test_readahead_base 16384
11917         test_readahead_base 16385
11918         test_readahead_base 16383
11919
11920         # file size: 1M + 1 = 1048576 + 1
11921         test_readahead_base 1048577
11922         # file size: 1M + 16K
11923         test_readahead_base $((1048576 + 16384))
11924
11925         # file size: stripe_size * (stripe_count - 1) + 16K
11926         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11927         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11928         # file size: stripe_size * stripe_count + 16K
11929         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11930         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11931         # file size: 2 * stripe_size * stripe_count + 16K
11932         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11933         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11934 }
11935 run_test 101m "read ahead for small file and last stripe of the file"
11936
11937 setup_test102() {
11938         test_mkdir $DIR/$tdir
11939         chown $RUNAS_ID $DIR/$tdir
11940         STRIPE_SIZE=65536
11941         STRIPE_OFFSET=1
11942         STRIPE_COUNT=$OSTCOUNT
11943         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11944
11945         trap cleanup_test102 EXIT
11946         cd $DIR
11947         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11948         cd $DIR/$tdir
11949         for num in 1 2 3 4; do
11950                 for count in $(seq 1 $STRIPE_COUNT); do
11951                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11952                                 local size=`expr $STRIPE_SIZE \* $num`
11953                                 local file=file"$num-$idx-$count"
11954                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11955                         done
11956                 done
11957         done
11958
11959         cd $DIR
11960         $1 tar cf $TMP/f102.tar $tdir --xattrs
11961 }
11962
11963 cleanup_test102() {
11964         trap 0
11965         rm -f $TMP/f102.tar
11966         rm -rf $DIR/d0.sanity/d102
11967 }
11968
11969 test_102a() {
11970         [ "$UID" != 0 ] && skip "must run as root"
11971         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11972                 skip_env "must have user_xattr"
11973
11974         [ -z "$(which setfattr 2>/dev/null)" ] &&
11975                 skip_env "could not find setfattr"
11976
11977         local testfile=$DIR/$tfile
11978
11979         touch $testfile
11980         echo "set/get xattr..."
11981         setfattr -n trusted.name1 -v value1 $testfile ||
11982                 error "setfattr -n trusted.name1=value1 $testfile failed"
11983         getfattr -n trusted.name1 $testfile 2> /dev/null |
11984           grep "trusted.name1=.value1" ||
11985                 error "$testfile missing trusted.name1=value1"
11986
11987         setfattr -n user.author1 -v author1 $testfile ||
11988                 error "setfattr -n user.author1=author1 $testfile failed"
11989         getfattr -n user.author1 $testfile 2> /dev/null |
11990           grep "user.author1=.author1" ||
11991                 error "$testfile missing trusted.author1=author1"
11992
11993         echo "listxattr..."
11994         setfattr -n trusted.name2 -v value2 $testfile ||
11995                 error "$testfile unable to set trusted.name2"
11996         setfattr -n trusted.name3 -v value3 $testfile ||
11997                 error "$testfile unable to set trusted.name3"
11998         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11999             grep "trusted.name" | wc -l) -eq 3 ] ||
12000                 error "$testfile missing 3 trusted.name xattrs"
12001
12002         setfattr -n user.author2 -v author2 $testfile ||
12003                 error "$testfile unable to set user.author2"
12004         setfattr -n user.author3 -v author3 $testfile ||
12005                 error "$testfile unable to set user.author3"
12006         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12007             grep "user.author" | wc -l) -eq 3 ] ||
12008                 error "$testfile missing 3 user.author xattrs"
12009
12010         echo "remove xattr..."
12011         setfattr -x trusted.name1 $testfile ||
12012                 error "$testfile error deleting trusted.name1"
12013         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12014                 error "$testfile did not delete trusted.name1 xattr"
12015
12016         setfattr -x user.author1 $testfile ||
12017                 error "$testfile error deleting user.author1"
12018         echo "set lustre special xattr ..."
12019         $LFS setstripe -c1 $testfile
12020         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12021                 awk -F "=" '/trusted.lov/ { print $2 }' )
12022         setfattr -n "trusted.lov" -v $lovea $testfile ||
12023                 error "$testfile doesn't ignore setting trusted.lov again"
12024         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12025                 error "$testfile allow setting invalid trusted.lov"
12026         rm -f $testfile
12027 }
12028 run_test 102a "user xattr test =================================="
12029
12030 check_102b_layout() {
12031         local layout="$*"
12032         local testfile=$DIR/$tfile
12033
12034         echo "test layout '$layout'"
12035         $LFS setstripe $layout $testfile || error "setstripe failed"
12036         $LFS getstripe -y $testfile
12037
12038         echo "get/set/list trusted.lov xattr ..." # b=10930
12039         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12040         [[ "$value" =~ "trusted.lov" ]] ||
12041                 error "can't get trusted.lov from $testfile"
12042         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12043                 error "getstripe failed"
12044
12045         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12046
12047         value=$(cut -d= -f2 <<<$value)
12048         # LU-13168: truncated xattr should fail if short lov_user_md header
12049         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12050                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12051         for len in $lens; do
12052                 echo "setfattr $len $testfile.2"
12053                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12054                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12055         done
12056         local stripe_size=$($LFS getstripe -S $testfile.2)
12057         local stripe_count=$($LFS getstripe -c $testfile.2)
12058         [[ $stripe_size -eq 65536 ]] ||
12059                 error "stripe size $stripe_size != 65536"
12060         [[ $stripe_count -eq $stripe_count_orig ]] ||
12061                 error "stripe count $stripe_count != $stripe_count_orig"
12062         rm $testfile $testfile.2
12063 }
12064
12065 test_102b() {
12066         [ -z "$(which setfattr 2>/dev/null)" ] &&
12067                 skip_env "could not find setfattr"
12068         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12069
12070         # check plain layout
12071         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12072
12073         # and also check composite layout
12074         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12075
12076 }
12077 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12078
12079 test_102c() {
12080         [ -z "$(which setfattr 2>/dev/null)" ] &&
12081                 skip_env "could not find setfattr"
12082         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12083
12084         # b10930: get/set/list lustre.lov xattr
12085         echo "get/set/list lustre.lov xattr ..."
12086         test_mkdir $DIR/$tdir
12087         chown $RUNAS_ID $DIR/$tdir
12088         local testfile=$DIR/$tdir/$tfile
12089         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12090                 error "setstripe failed"
12091         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12092                 error "getstripe failed"
12093         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12094         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12095
12096         local testfile2=${testfile}2
12097         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12098                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12099
12100         $RUNAS $MCREATE $testfile2
12101         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12102         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12103         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12104         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12105         [ $stripe_count -eq $STRIPECOUNT ] ||
12106                 error "stripe count $stripe_count != $STRIPECOUNT"
12107 }
12108 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12109
12110 compare_stripe_info1() {
12111         local stripe_index_all_zero=true
12112
12113         for num in 1 2 3 4; do
12114                 for count in $(seq 1 $STRIPE_COUNT); do
12115                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12116                                 local size=$((STRIPE_SIZE * num))
12117                                 local file=file"$num-$offset-$count"
12118                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12119                                 [[ $stripe_size -ne $size ]] &&
12120                                     error "$file: size $stripe_size != $size"
12121                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12122                                 # allow fewer stripes to be created, ORI-601
12123                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12124                                     error "$file: count $stripe_count != $count"
12125                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12126                                 [[ $stripe_index -ne 0 ]] &&
12127                                         stripe_index_all_zero=false
12128                         done
12129                 done
12130         done
12131         $stripe_index_all_zero &&
12132                 error "all files are being extracted starting from OST index 0"
12133         return 0
12134 }
12135
12136 have_xattrs_include() {
12137         tar --help | grep -q xattrs-include &&
12138                 echo --xattrs-include="lustre.*"
12139 }
12140
12141 test_102d() {
12142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12143         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12144
12145         XINC=$(have_xattrs_include)
12146         setup_test102
12147         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12148         cd $DIR/$tdir/$tdir
12149         compare_stripe_info1
12150 }
12151 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12152
12153 test_102f() {
12154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12155         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12156
12157         XINC=$(have_xattrs_include)
12158         setup_test102
12159         test_mkdir $DIR/$tdir.restore
12160         cd $DIR
12161         tar cf - --xattrs $tdir | tar xf - \
12162                 -C $DIR/$tdir.restore --xattrs $XINC
12163         cd $DIR/$tdir.restore/$tdir
12164         compare_stripe_info1
12165 }
12166 run_test 102f "tar copy files, not keep osts"
12167
12168 grow_xattr() {
12169         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12170                 skip "must have user_xattr"
12171         [ -z "$(which setfattr 2>/dev/null)" ] &&
12172                 skip_env "could not find setfattr"
12173         [ -z "$(which getfattr 2>/dev/null)" ] &&
12174                 skip_env "could not find getfattr"
12175
12176         local xsize=${1:-1024}  # in bytes
12177         local file=$DIR/$tfile
12178         local value="$(generate_string $xsize)"
12179         local xbig=trusted.big
12180         local toobig=$2
12181
12182         touch $file
12183         log "save $xbig on $file"
12184         if [ -z "$toobig" ]
12185         then
12186                 setfattr -n $xbig -v $value $file ||
12187                         error "saving $xbig on $file failed"
12188         else
12189                 setfattr -n $xbig -v $value $file &&
12190                         error "saving $xbig on $file succeeded"
12191                 return 0
12192         fi
12193
12194         local orig=$(get_xattr_value $xbig $file)
12195         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12196
12197         local xsml=trusted.sml
12198         log "save $xsml on $file"
12199         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12200
12201         local new=$(get_xattr_value $xbig $file)
12202         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12203
12204         log "grow $xsml on $file"
12205         setfattr -n $xsml -v "$value" $file ||
12206                 error "growing $xsml on $file failed"
12207
12208         new=$(get_xattr_value $xbig $file)
12209         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12210         log "$xbig still valid after growing $xsml"
12211
12212         rm -f $file
12213 }
12214
12215 test_102h() { # bug 15777
12216         grow_xattr 1024
12217 }
12218 run_test 102h "grow xattr from inside inode to external block"
12219
12220 test_102ha() {
12221         large_xattr_enabled || skip_env "ea_inode feature disabled"
12222
12223         echo "setting xattr of max xattr size: $(max_xattr_size)"
12224         grow_xattr $(max_xattr_size)
12225
12226         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12227         echo "This should fail:"
12228         grow_xattr $(($(max_xattr_size) + 10)) 1
12229 }
12230 run_test 102ha "grow xattr from inside inode to external inode"
12231
12232 test_102i() { # bug 17038
12233         [ -z "$(which getfattr 2>/dev/null)" ] &&
12234                 skip "could not find getfattr"
12235
12236         touch $DIR/$tfile
12237         ln -s $DIR/$tfile $DIR/${tfile}link
12238         getfattr -n trusted.lov $DIR/$tfile ||
12239                 error "lgetxattr on $DIR/$tfile failed"
12240         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12241                 grep -i "no such attr" ||
12242                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12243         rm -f $DIR/$tfile $DIR/${tfile}link
12244 }
12245 run_test 102i "lgetxattr test on symbolic link ============"
12246
12247 test_102j() {
12248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12249         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12250
12251         XINC=$(have_xattrs_include)
12252         setup_test102 "$RUNAS"
12253         chown $RUNAS_ID $DIR/$tdir
12254         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12255         cd $DIR/$tdir/$tdir
12256         compare_stripe_info1 "$RUNAS"
12257 }
12258 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12259
12260 test_102k() {
12261         [ -z "$(which setfattr 2>/dev/null)" ] &&
12262                 skip "could not find setfattr"
12263
12264         touch $DIR/$tfile
12265         # b22187 just check that does not crash for regular file.
12266         setfattr -n trusted.lov $DIR/$tfile
12267         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12268         local test_kdir=$DIR/$tdir
12269         test_mkdir $test_kdir
12270         local default_size=$($LFS getstripe -S $test_kdir)
12271         local default_count=$($LFS getstripe -c $test_kdir)
12272         local default_offset=$($LFS getstripe -i $test_kdir)
12273         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12274                 error 'dir setstripe failed'
12275         setfattr -n trusted.lov $test_kdir
12276         local stripe_size=$($LFS getstripe -S $test_kdir)
12277         local stripe_count=$($LFS getstripe -c $test_kdir)
12278         local stripe_offset=$($LFS getstripe -i $test_kdir)
12279         [ $stripe_size -eq $default_size ] ||
12280                 error "stripe size $stripe_size != $default_size"
12281         [ $stripe_count -eq $default_count ] ||
12282                 error "stripe count $stripe_count != $default_count"
12283         [ $stripe_offset -eq $default_offset ] ||
12284                 error "stripe offset $stripe_offset != $default_offset"
12285         rm -rf $DIR/$tfile $test_kdir
12286 }
12287 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12288
12289 test_102l() {
12290         [ -z "$(which getfattr 2>/dev/null)" ] &&
12291                 skip "could not find getfattr"
12292
12293         # LU-532 trusted. xattr is invisible to non-root
12294         local testfile=$DIR/$tfile
12295
12296         touch $testfile
12297
12298         echo "listxattr as user..."
12299         chown $RUNAS_ID $testfile
12300         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12301             grep -q "trusted" &&
12302                 error "$testfile trusted xattrs are user visible"
12303
12304         return 0;
12305 }
12306 run_test 102l "listxattr size test =================================="
12307
12308 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12309         local path=$DIR/$tfile
12310         touch $path
12311
12312         listxattr_size_check $path || error "listattr_size_check $path failed"
12313 }
12314 run_test 102m "Ensure listxattr fails on small bufffer ========"
12315
12316 cleanup_test102
12317
12318 getxattr() { # getxattr path name
12319         # Return the base64 encoding of the value of xattr name on path.
12320         local path=$1
12321         local name=$2
12322
12323         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12324         # file: $path
12325         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12326         #
12327         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12328
12329         getfattr --absolute-names --encoding=base64 --name=$name $path |
12330                 awk -F= -v name=$name '$1 == name {
12331                         print substr($0, index($0, "=") + 1);
12332         }'
12333 }
12334
12335 test_102n() { # LU-4101 mdt: protect internal xattrs
12336         [ -z "$(which setfattr 2>/dev/null)" ] &&
12337                 skip "could not find setfattr"
12338         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12339         then
12340                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12341         fi
12342
12343         local file0=$DIR/$tfile.0
12344         local file1=$DIR/$tfile.1
12345         local xattr0=$TMP/$tfile.0
12346         local xattr1=$TMP/$tfile.1
12347         local namelist="lov lma lmv link fid version som hsm"
12348         local name
12349         local value
12350
12351         rm -rf $file0 $file1 $xattr0 $xattr1
12352         touch $file0 $file1
12353
12354         # Get 'before' xattrs of $file1.
12355         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12356
12357         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12358                 namelist+=" lfsck_namespace"
12359         for name in $namelist; do
12360                 # Try to copy xattr from $file0 to $file1.
12361                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12362
12363                 setfattr --name=trusted.$name --value="$value" $file1 ||
12364                         error "setxattr 'trusted.$name' failed"
12365
12366                 # Try to set a garbage xattr.
12367                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12368
12369                 if [[ x$name == "xlov" ]]; then
12370                         setfattr --name=trusted.lov --value="$value" $file1 &&
12371                         error "setxattr invalid 'trusted.lov' success"
12372                 else
12373                         setfattr --name=trusted.$name --value="$value" $file1 ||
12374                                 error "setxattr invalid 'trusted.$name' failed"
12375                 fi
12376
12377                 # Try to remove the xattr from $file1. We don't care if this
12378                 # appears to succeed or fail, we just don't want there to be
12379                 # any changes or crashes.
12380                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12381         done
12382
12383         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12384         then
12385                 name="lfsck_ns"
12386                 # Try to copy xattr from $file0 to $file1.
12387                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12388
12389                 setfattr --name=trusted.$name --value="$value" $file1 ||
12390                         error "setxattr 'trusted.$name' failed"
12391
12392                 # Try to set a garbage xattr.
12393                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12394
12395                 setfattr --name=trusted.$name --value="$value" $file1 ||
12396                         error "setxattr 'trusted.$name' failed"
12397
12398                 # Try to remove the xattr from $file1. We don't care if this
12399                 # appears to succeed or fail, we just don't want there to be
12400                 # any changes or crashes.
12401                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12402         fi
12403
12404         # Get 'after' xattrs of file1.
12405         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12406
12407         if ! diff $xattr0 $xattr1; then
12408                 error "before and after xattrs of '$file1' differ"
12409         fi
12410
12411         rm -rf $file0 $file1 $xattr0 $xattr1
12412
12413         return 0
12414 }
12415 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12416
12417 test_102p() { # LU-4703 setxattr did not check ownership
12418         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12419                 skip "MDS needs to be at least 2.5.56"
12420
12421         local testfile=$DIR/$tfile
12422
12423         touch $testfile
12424
12425         echo "setfacl as user..."
12426         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12427         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12428
12429         echo "setfattr as user..."
12430         setfacl -m "u:$RUNAS_ID:---" $testfile
12431         $RUNAS setfattr -x system.posix_acl_access $testfile
12432         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12433 }
12434 run_test 102p "check setxattr(2) correctly fails without permission"
12435
12436 test_102q() {
12437         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12438                 skip "MDS needs to be at least 2.6.92"
12439
12440         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12441 }
12442 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12443
12444 test_102r() {
12445         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12446                 skip "MDS needs to be at least 2.6.93"
12447
12448         touch $DIR/$tfile || error "touch"
12449         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12450         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12451         rm $DIR/$tfile || error "rm"
12452
12453         #normal directory
12454         mkdir -p $DIR/$tdir || error "mkdir"
12455         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12456         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12457         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12458                 error "$testfile error deleting user.author1"
12459         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12460                 grep "user.$(basename $tdir)" &&
12461                 error "$tdir did not delete user.$(basename $tdir)"
12462         rmdir $DIR/$tdir || error "rmdir"
12463
12464         #striped directory
12465         test_mkdir $DIR/$tdir
12466         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12467         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12468         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12469                 error "$testfile error deleting user.author1"
12470         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12471                 grep "user.$(basename $tdir)" &&
12472                 error "$tdir did not delete user.$(basename $tdir)"
12473         rmdir $DIR/$tdir || error "rm striped dir"
12474 }
12475 run_test 102r "set EAs with empty values"
12476
12477 test_102s() {
12478         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12479                 skip "MDS needs to be at least 2.11.52"
12480
12481         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12482
12483         save_lustre_params client "llite.*.xattr_cache" > $save
12484
12485         for cache in 0 1; do
12486                 lctl set_param llite.*.xattr_cache=$cache
12487
12488                 rm -f $DIR/$tfile
12489                 touch $DIR/$tfile || error "touch"
12490                 for prefix in lustre security system trusted user; do
12491                         # Note getxattr() may fail with 'Operation not
12492                         # supported' or 'No such attribute' depending
12493                         # on prefix and cache.
12494                         getfattr -n $prefix.n102s $DIR/$tfile &&
12495                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12496                 done
12497         done
12498
12499         restore_lustre_params < $save
12500 }
12501 run_test 102s "getting nonexistent xattrs should fail"
12502
12503 test_102t() {
12504         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12505                 skip "MDS needs to be at least 2.11.52"
12506
12507         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12508
12509         save_lustre_params client "llite.*.xattr_cache" > $save
12510
12511         for cache in 0 1; do
12512                 lctl set_param llite.*.xattr_cache=$cache
12513
12514                 for buf_size in 0 256; do
12515                         rm -f $DIR/$tfile
12516                         touch $DIR/$tfile || error "touch"
12517                         setfattr -n user.multiop $DIR/$tfile
12518                         $MULTIOP $DIR/$tfile oa$buf_size ||
12519                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12520                 done
12521         done
12522
12523         restore_lustre_params < $save
12524 }
12525 run_test 102t "zero length xattr values handled correctly"
12526
12527 run_acl_subtest()
12528 {
12529         local test=$LUSTRE/tests/acl/$1.test
12530         local tmp=$(mktemp -t $1-XXXXXX).test
12531         local bin=$2
12532         local dmn=$3
12533         local grp=$4
12534         local nbd=$5
12535         export LANG=C
12536
12537
12538         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12539         local sedgroups="-e s/:users/:$grp/g"
12540         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12541
12542         sed $sedusers $sedgroups < $test > $tmp
12543         stack_trap "rm -f $tmp"
12544         [[ -s $tmp ]] || error "sed failed to create test script"
12545
12546         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12547         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12548 }
12549
12550 test_103a() {
12551         [ "$UID" != 0 ] && skip "must run as root"
12552         $GSS && skip_env "could not run under gss"
12553         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12554                 skip_env "must have acl enabled"
12555         which setfacl || skip_env "could not find setfacl"
12556         remote_mds_nodsh && skip "remote MDS with nodsh"
12557
12558         local mdts=$(comma_list $(mdts_nodes))
12559         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12560
12561         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12562         stack_trap "[[ -z \"$saved\" ]] || \
12563                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12564
12565         ACLBIN=${ACLBIN:-"bin"}
12566         ACLDMN=${ACLDMN:-"daemon"}
12567         ACLGRP=${ACLGRP:-"users"}
12568         ACLNBD=${ACLNBD:-"nobody"}
12569
12570         if ! id $ACLBIN ||
12571            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12572                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12573                 ACLBIN=$USER0
12574                 if ! id $ACLBIN ; then
12575                         cat /etc/passwd
12576                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12577                 fi
12578         fi
12579         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12580            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12581                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12582                 ACLDMN=$USER1
12583                 if ! id $ACLDMN ; then
12584                         cat /etc/passwd
12585                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12586                 fi
12587         fi
12588         if ! getent group $ACLGRP; then
12589                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12590                 ACLGRP="$TSTUSR"
12591                 if ! getent group $ACLGRP; then
12592                         echo "cannot find group '$ACLGRP', adding it"
12593                         cat /etc/group
12594                         add_group 60000 $ACLGRP
12595                 fi
12596         fi
12597
12598         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12599         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12600         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12601
12602         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12603                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12604                 ACLGRP="$TSTUSR"
12605                 if ! getent group $ACLGRP; then
12606                         echo "cannot find group '$ACLGRP', adding it"
12607                         cat /etc/group
12608                         add_group 60000 $ACLGRP
12609                 fi
12610                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12611                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12612                         cat /etc/group
12613                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12614                 fi
12615         fi
12616
12617         gpasswd -a $ACLDMN $ACLBIN ||
12618                 error "setting client group failed"             # LU-5641
12619         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12620                 error "setting MDS group failed"                # LU-5641
12621
12622         declare -a identity_old
12623
12624         for ((num = 1; num <= $MDSCOUNT; num++)); do
12625                 switch_identity $num true || identity_old[$num]=$?
12626         done
12627
12628         SAVE_UMASK=$(umask)
12629         umask 0022
12630         mkdir -p $DIR/$tdir
12631         cd $DIR/$tdir
12632
12633         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12634         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12635         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12636         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12637         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12638         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12639         if ! id -u $ACLNBD ||
12640            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12641                 ACLNBD="nfsnobody"
12642                 if ! id -u $ACLNBD; then
12643                         ACLNBD=""
12644                 fi
12645         fi
12646         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12647                 add_group $(id -u $ACLNBD) $ACLNBD
12648                 if ! getent group $ACLNBD; then
12649                         ACLNBD=""
12650                 fi
12651         fi
12652         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12653            [[ -n "$ACLNBD" ]] && which setfattr; then
12654                 run_acl_subtest permissions_xattr \
12655                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12656         elif [[ -z "$ACLNBD" ]]; then
12657                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12658         else
12659                 echo "skip 'permission_xattr' test - missing setfattr command"
12660         fi
12661         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12662
12663         # inheritance test got from HP
12664         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12665         chmod +x make-tree || error "chmod +x failed"
12666         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12667         rm -f make-tree
12668
12669         echo "LU-974 ignore umask when acl is enabled..."
12670         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12671         if [ $MDSCOUNT -ge 2 ]; then
12672                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12673         fi
12674
12675         echo "LU-2561 newly created file is same size as directory..."
12676         if [ "$mds1_FSTYPE" != "zfs" ]; then
12677                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12678         else
12679                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12680         fi
12681
12682         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12683
12684         cd $SAVE_PWD
12685         umask $SAVE_UMASK
12686
12687         for ((num = 1; num <= $MDSCOUNT; num++)); do
12688                 if [[ "${identity_old[$num]}" == 1 ]]; then
12689                         switch_identity $num false || identity_old[$num]=$?
12690                 fi
12691         done
12692 }
12693 run_test 103a "acl test"
12694
12695 test_103b() {
12696         declare -a pids
12697         local U
12698
12699         stack_trap "rm -f $DIR/$tfile.*"
12700         for U in {0..511}; do
12701                 {
12702                 local O=$(printf "%04o" $U)
12703
12704                 umask $(printf "%04o" $((511 ^ $O)))
12705                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12706                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12707
12708                 (( $S == ($O & 0666) )) ||
12709                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12710
12711                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12712                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12713                 (( $S == ($O & 0666) )) ||
12714                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12715
12716                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12717                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12718                 (( $S == ($O & 0666) )) ||
12719                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12720                 rm -f $DIR/$tfile.[smp]$0
12721                 } &
12722                 local pid=$!
12723
12724                 # limit the concurrently running threads to 64. LU-11878
12725                 local idx=$((U % 64))
12726                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12727                 pids[idx]=$pid
12728         done
12729         wait
12730 }
12731 run_test 103b "umask lfs setstripe"
12732
12733 test_103c() {
12734         mkdir -p $DIR/$tdir
12735         cp -rp $DIR/$tdir $DIR/$tdir.bak
12736
12737         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12738                 error "$DIR/$tdir shouldn't contain default ACL"
12739         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12740                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12741         true
12742 }
12743 run_test 103c "'cp -rp' won't set empty acl"
12744
12745 test_103e() {
12746         local numacl
12747         local fileacl
12748         local saved_debug=$($LCTL get_param -n debug)
12749
12750         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12751                 skip "MDS needs to be at least 2.14.52"
12752
12753         large_xattr_enabled || skip_env "ea_inode feature disabled"
12754
12755         mkdir -p $DIR/$tdir
12756         # add big LOV EA to cause reply buffer overflow earlier
12757         $LFS setstripe -C 1000 $DIR/$tdir
12758         lctl set_param mdc.*-mdc*.stats=clear
12759
12760         $LCTL set_param debug=0
12761         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12762         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12763
12764         # add a large number of default ACLs (expect 8000+ for 2.13+)
12765         for U in {2..7000}; do
12766                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12767                         error "Able to add just $U default ACLs"
12768         done
12769         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12770         echo "$numacl default ACLs created"
12771
12772         stat $DIR/$tdir || error "Cannot stat directory"
12773         # check file creation
12774         touch $DIR/$tdir/$tfile ||
12775                 error "failed to create $tfile with $numacl default ACLs"
12776         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12777         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12778         echo "$fileacl ACLs were inherited"
12779         (( $fileacl == $numacl )) ||
12780                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12781         # check that new ACLs creation adds new ACLs to inherited ACLs
12782         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12783                 error "Cannot set new ACL"
12784         numacl=$((numacl + 1))
12785         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12786         (( $fileacl == $numacl )) ||
12787                 error "failed to add new ACL: $fileacl != $numacl as expected"
12788         # adds more ACLs to a file to reach their maximum at 8000+
12789         numacl=0
12790         for U in {20000..25000}; do
12791                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12792                 numacl=$((numacl + 1))
12793         done
12794         echo "Added $numacl more ACLs to the file"
12795         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12796         echo "Total $fileacl ACLs in file"
12797         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12798         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12799         rmdir $DIR/$tdir || error "Cannot remove directory"
12800 }
12801 run_test 103e "inheritance of big amount of default ACLs"
12802
12803 test_103f() {
12804         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12805                 skip "MDS needs to be at least 2.14.51"
12806
12807         large_xattr_enabled || skip_env "ea_inode feature disabled"
12808
12809         # enable changelog to consume more internal MDD buffers
12810         changelog_register
12811
12812         mkdir -p $DIR/$tdir
12813         # add big LOV EA
12814         $LFS setstripe -C 1000 $DIR/$tdir
12815         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12816         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12817         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12818         rmdir $DIR/$tdir || error "Cannot remove directory"
12819 }
12820 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12821
12822 test_104a() {
12823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12824
12825         touch $DIR/$tfile
12826         lfs df || error "lfs df failed"
12827         lfs df -ih || error "lfs df -ih failed"
12828         lfs df -h $DIR || error "lfs df -h $DIR failed"
12829         lfs df -i $DIR || error "lfs df -i $DIR failed"
12830         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12831         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12832
12833         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12834         lctl --device %$OSC deactivate
12835         lfs df || error "lfs df with deactivated OSC failed"
12836         lctl --device %$OSC activate
12837         # wait the osc back to normal
12838         wait_osc_import_ready client ost
12839
12840         lfs df || error "lfs df with reactivated OSC failed"
12841         rm -f $DIR/$tfile
12842 }
12843 run_test 104a "lfs df [-ih] [path] test ========================="
12844
12845 test_104b() {
12846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12847         [ $RUNAS_ID -eq $UID ] &&
12848                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12849
12850         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12851                         grep "Permission denied" | wc -l)))
12852         if [ $denied_cnt -ne 0 ]; then
12853                 error "lfs check servers test failed"
12854         fi
12855 }
12856 run_test 104b "$RUNAS lfs check servers test ===================="
12857
12858 #
12859 # Verify $1 is within range of $2.
12860 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12861 # $1 is <= 2% of $2. Else Fail.
12862 #
12863 value_in_range() {
12864         # Strip all units (M, G, T)
12865         actual=$(echo $1 | tr -d A-Z)
12866         expect=$(echo $2 | tr -d A-Z)
12867
12868         expect_lo=$(($expect * 98 / 100)) # 2% below
12869         expect_hi=$(($expect * 102 / 100)) # 2% above
12870
12871         # permit 2% drift above and below
12872         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12873 }
12874
12875 test_104c() {
12876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12877         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12878
12879         local ost_param="osd-zfs.$FSNAME-OST0000."
12880         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12881         local ofacets=$(get_facets OST)
12882         local mfacets=$(get_facets MDS)
12883         local saved_ost_blocks=
12884         local saved_mdt_blocks=
12885
12886         echo "Before recordsize change"
12887         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12888         df=($(df -h | grep "$MOUNT"$))
12889
12890         # For checking.
12891         echo "lfs output : ${lfs_df[*]}"
12892         echo "df  output : ${df[*]}"
12893
12894         for facet in ${ofacets//,/ }; do
12895                 if [ -z $saved_ost_blocks ]; then
12896                         saved_ost_blocks=$(do_facet $facet \
12897                                 lctl get_param -n $ost_param.blocksize)
12898                         echo "OST Blocksize: $saved_ost_blocks"
12899                 fi
12900                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12901                 do_facet $facet zfs set recordsize=32768 $ost
12902         done
12903
12904         # BS too small. Sufficient for functional testing.
12905         for facet in ${mfacets//,/ }; do
12906                 if [ -z $saved_mdt_blocks ]; then
12907                         saved_mdt_blocks=$(do_facet $facet \
12908                                 lctl get_param -n $mdt_param.blocksize)
12909                         echo "MDT Blocksize: $saved_mdt_blocks"
12910                 fi
12911                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12912                 do_facet $facet zfs set recordsize=32768 $mdt
12913         done
12914
12915         # Give new values chance to reflect change
12916         sleep 2
12917
12918         echo "After recordsize change"
12919         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12920         df_after=($(df -h | grep "$MOUNT"$))
12921
12922         # For checking.
12923         echo "lfs output : ${lfs_df_after[*]}"
12924         echo "df  output : ${df_after[*]}"
12925
12926         # Verify lfs df
12927         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12928                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12929         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12930                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12931         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12932                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12933
12934         # Verify df
12935         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12936                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12937         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12938                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12939         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12940                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12941
12942         # Restore MDT recordize back to original
12943         for facet in ${mfacets//,/ }; do
12944                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12945                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12946         done
12947
12948         # Restore OST recordize back to original
12949         for facet in ${ofacets//,/ }; do
12950                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12951                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12952         done
12953
12954         return 0
12955 }
12956 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12957
12958 test_104d() {
12959         (( $RUNAS_ID != $UID )) ||
12960                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12961
12962         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12963                 skip "lustre version doesn't support lctl dl with non-root"
12964
12965         # debugfs only allows root users to access files, so the
12966         # previous move of the "devices" file to debugfs broke
12967         # "lctl dl" for non-root users. The LU-9680 Netlink
12968         # interface again allows non-root users to list devices.
12969         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12970                 error "lctl dl doesn't work for non root"
12971
12972         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12973         [ "$ost_count" -eq $OSTCOUNT ]  ||
12974                 error "lctl dl reports wrong number of OST devices"
12975
12976         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12977         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12978                 error "lctl dl reports wrong number of MDT devices"
12979 }
12980 run_test 104d "$RUNAS lctl dl test"
12981
12982 test_105a() {
12983         # doesn't work on 2.4 kernels
12984         touch $DIR/$tfile
12985         if $(flock_is_enabled); then
12986                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12987         else
12988                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12989         fi
12990         rm -f $DIR/$tfile
12991 }
12992 run_test 105a "flock when mounted without -o flock test ========"
12993
12994 test_105b() {
12995         touch $DIR/$tfile
12996         if $(flock_is_enabled); then
12997                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12998         else
12999                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13000         fi
13001         rm -f $DIR/$tfile
13002 }
13003 run_test 105b "fcntl when mounted without -o flock test ========"
13004
13005 test_105c() {
13006         touch $DIR/$tfile
13007         if $(flock_is_enabled); then
13008                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13009         else
13010                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13011         fi
13012         rm -f $DIR/$tfile
13013 }
13014 run_test 105c "lockf when mounted without -o flock test"
13015
13016 test_105d() { # bug 15924
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018
13019         test_mkdir $DIR/$tdir
13020         flock_is_enabled || skip_env "mount w/o flock enabled"
13021         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13022         $LCTL set_param fail_loc=0x80000315
13023         flocks_test 2 $DIR/$tdir
13024 }
13025 run_test 105d "flock race (should not freeze) ========"
13026
13027 test_105e() { # bug 22660 && 22040
13028         flock_is_enabled || skip_env "mount w/o flock enabled"
13029
13030         touch $DIR/$tfile
13031         flocks_test 3 $DIR/$tfile
13032 }
13033 run_test 105e "Two conflicting flocks from same process"
13034
13035 wait_end() {
13036         echo $*
13037         while :; do
13038                 [ -f $TMP/${tfile}_sTOP ] && return
13039                 sleep 1
13040         done
13041 }
13042
13043 test_105f() {
13044         flock_is_enabled || skip_env "mount w/o flock enabled"
13045
13046         local pmax=$(ulimit -u)
13047         local i=0
13048         touch $DIR/$tfile
13049         [ $pmax -gt 20 ] && pmax=20
13050         for((i=0; i <= $pmax; i++)) {
13051                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13052         }
13053         for((i=0; i <= 10; i++)) {
13054                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13055                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13056                 [ $locks -ge $pmax ] && break
13057                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13058                 sleep 1
13059         }
13060         touch $TMP/${tfile}_sTOP
13061         wait
13062         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13063 }
13064 run_test 105f "Enqueue same range flocks"
13065
13066 test_106() { #bug 10921
13067         test_mkdir $DIR/$tdir
13068         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13069         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13070 }
13071 run_test 106 "attempt exec of dir followed by chown of that dir"
13072
13073 test_107() {
13074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13075
13076         CDIR=`pwd`
13077         local file=core
13078
13079         cd $DIR
13080         rm -f $file
13081
13082         local save_pattern=$(sysctl -n kernel.core_pattern)
13083         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13084         sysctl -w kernel.core_pattern=$file
13085         sysctl -w kernel.core_uses_pid=0
13086
13087         ulimit -c unlimited
13088         sleep 60 &
13089         SLEEPPID=$!
13090
13091         sleep 1
13092
13093         kill -s 11 $SLEEPPID
13094         wait $SLEEPPID
13095         if [ -e $file ]; then
13096                 size=`stat -c%s $file`
13097                 [ $size -eq 0 ] && error "Fail to create core file $file"
13098         else
13099                 error "Fail to create core file $file"
13100         fi
13101         rm -f $file
13102         sysctl -w kernel.core_pattern=$save_pattern
13103         sysctl -w kernel.core_uses_pid=$save_uses_pid
13104         cd $CDIR
13105 }
13106 run_test 107 "Coredump on SIG"
13107
13108 test_110() {
13109         test_mkdir $DIR/$tdir
13110         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13111         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13112                 error "mkdir with 256 char should fail, but did not"
13113         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13114                 error "create with 255 char failed"
13115         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13116                 error "create with 256 char should fail, but did not"
13117
13118         ls -l $DIR/$tdir
13119         rm -rf $DIR/$tdir
13120 }
13121 run_test 110 "filename length checking"
13122
13123 test_116a() { # was previously test_116()
13124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13125         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13126         remote_mds_nodsh && skip "remote MDS with nodsh"
13127
13128         echo -n "Free space priority "
13129         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13130                 head -n1
13131         declare -a AVAIL
13132         free_min_max
13133
13134         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13135         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13136         stack_trap simple_cleanup_common
13137
13138         # Check if we need to generate uneven OSTs
13139         test_mkdir -p $DIR/$tdir/OST${MINI}
13140         local FILL=$((MINV / 4))
13141         local DIFF=$((MAXV - MINV))
13142         local DIFF2=$((DIFF * 100 / MINV))
13143
13144         local threshold=$(do_facet $SINGLEMDS \
13145                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13146         threshold=${threshold%%%}
13147         echo -n "Check for uneven OSTs: "
13148         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13149
13150         if [[ $DIFF2 -gt $threshold ]]; then
13151                 echo "ok"
13152                 echo "Don't need to fill OST$MINI"
13153         else
13154                 # generate uneven OSTs. Write 2% over the QOS threshold value
13155                 echo "no"
13156                 DIFF=$((threshold - DIFF2 + 2))
13157                 DIFF2=$((MINV * DIFF / 100))
13158                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13159                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13160                         error "setstripe failed"
13161                 DIFF=$((DIFF2 / 2048))
13162                 i=0
13163                 while [ $i -lt $DIFF ]; do
13164                         i=$((i + 1))
13165                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13166                                 bs=2M count=1 2>/dev/null
13167                         echo -n .
13168                 done
13169                 echo .
13170                 sync
13171                 sleep_maxage
13172                 free_min_max
13173         fi
13174
13175         DIFF=$((MAXV - MINV))
13176         DIFF2=$((DIFF * 100 / MINV))
13177         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13178         if [ $DIFF2 -gt $threshold ]; then
13179                 echo "ok"
13180         else
13181                 skip "QOS imbalance criteria not met"
13182         fi
13183
13184         MINI1=$MINI
13185         MINV1=$MINV
13186         MAXI1=$MAXI
13187         MAXV1=$MAXV
13188
13189         # now fill using QOS
13190         $LFS setstripe -c 1 $DIR/$tdir
13191         FILL=$((FILL / 200))
13192         if [ $FILL -gt 600 ]; then
13193                 FILL=600
13194         fi
13195         echo "writing $FILL files to QOS-assigned OSTs"
13196         i=0
13197         while [ $i -lt $FILL ]; do
13198                 i=$((i + 1))
13199                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13200                         count=1 2>/dev/null
13201                 echo -n .
13202         done
13203         echo "wrote $i 200k files"
13204         sync
13205         sleep_maxage
13206
13207         echo "Note: free space may not be updated, so measurements might be off"
13208         free_min_max
13209         DIFF2=$((MAXV - MINV))
13210         echo "free space delta: orig $DIFF final $DIFF2"
13211         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13212         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13213         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13214         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13215         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13216         if [[ $DIFF -gt 0 ]]; then
13217                 FILL=$((DIFF2 * 100 / DIFF - 100))
13218                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13219         fi
13220
13221         # Figure out which files were written where
13222         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13223                awk '/'$MINI1': / {print $2; exit}')
13224         echo $UUID
13225         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13226         echo "$MINC files created on smaller OST $MINI1"
13227         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13228                awk '/'$MAXI1': / {print $2; exit}')
13229         echo $UUID
13230         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13231         echo "$MAXC files created on larger OST $MAXI1"
13232         if [[ $MINC -gt 0 ]]; then
13233                 FILL=$((MAXC * 100 / MINC - 100))
13234                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13235         fi
13236         [[ $MAXC -gt $MINC ]] ||
13237                 error_ignore LU-9 "stripe QOS didn't balance free space"
13238 }
13239 run_test 116a "stripe QOS: free space balance ==================="
13240
13241 test_116b() { # LU-2093
13242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13243         remote_mds_nodsh && skip "remote MDS with nodsh"
13244
13245 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13246         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13247                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13248         [ -z "$old_rr" ] && skip "no QOS"
13249         do_facet $SINGLEMDS lctl set_param \
13250                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13251         mkdir -p $DIR/$tdir
13252         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13253         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13254         do_facet $SINGLEMDS lctl set_param fail_loc=0
13255         rm -rf $DIR/$tdir
13256         do_facet $SINGLEMDS lctl set_param \
13257                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13258 }
13259 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13260
13261 test_117() # bug 10891
13262 {
13263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13264
13265         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13266         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13267         lctl set_param fail_loc=0x21e
13268         > $DIR/$tfile || error "truncate failed"
13269         lctl set_param fail_loc=0
13270         echo "Truncate succeeded."
13271         rm -f $DIR/$tfile
13272 }
13273 run_test 117 "verify osd extend =========="
13274
13275 NO_SLOW_RESENDCOUNT=4
13276 export OLD_RESENDCOUNT=""
13277 set_resend_count () {
13278         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13279         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13280         lctl set_param -n $PROC_RESENDCOUNT $1
13281         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13282 }
13283
13284 # for reduce test_118* time (b=14842)
13285 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13286
13287 # Reset async IO behavior after error case
13288 reset_async() {
13289         FILE=$DIR/reset_async
13290
13291         # Ensure all OSCs are cleared
13292         $LFS setstripe -c -1 $FILE
13293         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13294         sync
13295         rm $FILE
13296 }
13297
13298 test_118a() #bug 11710
13299 {
13300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13301
13302         reset_async
13303
13304         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13305         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13306         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13307
13308         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13309                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13310                 return 1;
13311         fi
13312         rm -f $DIR/$tfile
13313 }
13314 run_test 118a "verify O_SYNC works =========="
13315
13316 test_118b()
13317 {
13318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13319         remote_ost_nodsh && skip "remote OST with nodsh"
13320
13321         reset_async
13322
13323         #define OBD_FAIL_SRV_ENOENT 0x217
13324         set_nodes_failloc "$(osts_nodes)" 0x217
13325         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13326         RC=$?
13327         set_nodes_failloc "$(osts_nodes)" 0
13328         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13329         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13330                     grep -c writeback)
13331
13332         if [[ $RC -eq 0 ]]; then
13333                 error "Must return error due to dropped pages, rc=$RC"
13334                 return 1;
13335         fi
13336
13337         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13338                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13339                 return 1;
13340         fi
13341
13342         echo "Dirty pages not leaked on ENOENT"
13343
13344         # Due to the above error the OSC will issue all RPCs syncronously
13345         # until a subsequent RPC completes successfully without error.
13346         $MULTIOP $DIR/$tfile Ow4096yc
13347         rm -f $DIR/$tfile
13348
13349         return 0
13350 }
13351 run_test 118b "Reclaim dirty pages on fatal error =========="
13352
13353 test_118c()
13354 {
13355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13356
13357         # for 118c, restore the original resend count, LU-1940
13358         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13359                                 set_resend_count $OLD_RESENDCOUNT
13360         remote_ost_nodsh && skip "remote OST with nodsh"
13361
13362         reset_async
13363
13364         #define OBD_FAIL_OST_EROFS               0x216
13365         set_nodes_failloc "$(osts_nodes)" 0x216
13366
13367         # multiop should block due to fsync until pages are written
13368         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13369         MULTIPID=$!
13370         sleep 1
13371
13372         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13373                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13374         fi
13375
13376         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13377                     grep -c writeback)
13378         if [[ $WRITEBACK -eq 0 ]]; then
13379                 error "No page in writeback, writeback=$WRITEBACK"
13380         fi
13381
13382         set_nodes_failloc "$(osts_nodes)" 0
13383         wait $MULTIPID
13384         RC=$?
13385         if [[ $RC -ne 0 ]]; then
13386                 error "Multiop fsync failed, rc=$RC"
13387         fi
13388
13389         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13390         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13391                     grep -c writeback)
13392         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13393                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13394         fi
13395
13396         rm -f $DIR/$tfile
13397         echo "Dirty pages flushed via fsync on EROFS"
13398         return 0
13399 }
13400 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13401
13402 # continue to use small resend count to reduce test_118* time (b=14842)
13403 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13404
13405 test_118d()
13406 {
13407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13408         remote_ost_nodsh && skip "remote OST with nodsh"
13409
13410         reset_async
13411
13412         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13413         set_nodes_failloc "$(osts_nodes)" 0x214
13414         # multiop should block due to fsync until pages are written
13415         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13416         MULTIPID=$!
13417         sleep 1
13418
13419         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13420                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13421         fi
13422
13423         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13424                     grep -c writeback)
13425         if [[ $WRITEBACK -eq 0 ]]; then
13426                 error "No page in writeback, writeback=$WRITEBACK"
13427         fi
13428
13429         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13430         set_nodes_failloc "$(osts_nodes)" 0
13431
13432         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13433         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13434                     grep -c writeback)
13435         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13436                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13437         fi
13438
13439         rm -f $DIR/$tfile
13440         echo "Dirty pages gaurenteed flushed via fsync"
13441         return 0
13442 }
13443 run_test 118d "Fsync validation inject a delay of the bulk =========="
13444
13445 test_118f() {
13446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13447
13448         reset_async
13449
13450         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13451         lctl set_param fail_loc=0x8000040a
13452
13453         # Should simulate EINVAL error which is fatal
13454         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13455         RC=$?
13456         if [[ $RC -eq 0 ]]; then
13457                 error "Must return error due to dropped pages, rc=$RC"
13458         fi
13459
13460         lctl set_param fail_loc=0x0
13461
13462         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13463         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13464         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13465                     grep -c writeback)
13466         if [[ $LOCKED -ne 0 ]]; then
13467                 error "Locked pages remain in cache, locked=$LOCKED"
13468         fi
13469
13470         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13471                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13472         fi
13473
13474         rm -f $DIR/$tfile
13475         echo "No pages locked after fsync"
13476
13477         reset_async
13478         return 0
13479 }
13480 run_test 118f "Simulate unrecoverable OSC side error =========="
13481
13482 test_118g() {
13483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13484
13485         reset_async
13486
13487         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13488         lctl set_param fail_loc=0x406
13489
13490         # simulate local -ENOMEM
13491         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13492         RC=$?
13493
13494         lctl set_param fail_loc=0
13495         if [[ $RC -eq 0 ]]; then
13496                 error "Must return error due to dropped pages, rc=$RC"
13497         fi
13498
13499         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13500         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13501         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13502                         grep -c writeback)
13503         if [[ $LOCKED -ne 0 ]]; then
13504                 error "Locked pages remain in cache, locked=$LOCKED"
13505         fi
13506
13507         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13508                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13509         fi
13510
13511         rm -f $DIR/$tfile
13512         echo "No pages locked after fsync"
13513
13514         reset_async
13515         return 0
13516 }
13517 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13518
13519 test_118h() {
13520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13521         remote_ost_nodsh && skip "remote OST with nodsh"
13522
13523         reset_async
13524
13525         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13526         set_nodes_failloc "$(osts_nodes)" 0x20e
13527         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13528         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13529         RC=$?
13530
13531         set_nodes_failloc "$(osts_nodes)" 0
13532         if [[ $RC -eq 0 ]]; then
13533                 error "Must return error due to dropped pages, rc=$RC"
13534         fi
13535
13536         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13537         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13538         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13539                     grep -c writeback)
13540         if [[ $LOCKED -ne 0 ]]; then
13541                 error "Locked pages remain in cache, locked=$LOCKED"
13542         fi
13543
13544         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13545                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13546         fi
13547
13548         rm -f $DIR/$tfile
13549         echo "No pages locked after fsync"
13550
13551         return 0
13552 }
13553 run_test 118h "Verify timeout in handling recoverables errors  =========="
13554
13555 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13556
13557 test_118i() {
13558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13559         remote_ost_nodsh && skip "remote OST with nodsh"
13560
13561         reset_async
13562
13563         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13564         set_nodes_failloc "$(osts_nodes)" 0x20e
13565
13566         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13567         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13568         PID=$!
13569         sleep 5
13570         set_nodes_failloc "$(osts_nodes)" 0
13571
13572         wait $PID
13573         RC=$?
13574         if [[ $RC -ne 0 ]]; then
13575                 error "got error, but should be not, rc=$RC"
13576         fi
13577
13578         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13579         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13580         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13581         if [[ $LOCKED -ne 0 ]]; then
13582                 error "Locked pages remain in cache, locked=$LOCKED"
13583         fi
13584
13585         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13586                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13587         fi
13588
13589         rm -f $DIR/$tfile
13590         echo "No pages locked after fsync"
13591
13592         return 0
13593 }
13594 run_test 118i "Fix error before timeout in recoverable error  =========="
13595
13596 [ "$SLOW" = "no" ] && set_resend_count 4
13597
13598 test_118j() {
13599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13600         remote_ost_nodsh && skip "remote OST with nodsh"
13601
13602         reset_async
13603
13604         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13605         set_nodes_failloc "$(osts_nodes)" 0x220
13606
13607         # return -EIO from OST
13608         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13609         RC=$?
13610         set_nodes_failloc "$(osts_nodes)" 0x0
13611         if [[ $RC -eq 0 ]]; then
13612                 error "Must return error due to dropped pages, rc=$RC"
13613         fi
13614
13615         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13616         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13617         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13618         if [[ $LOCKED -ne 0 ]]; then
13619                 error "Locked pages remain in cache, locked=$LOCKED"
13620         fi
13621
13622         # in recoverable error on OST we want resend and stay until it finished
13623         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13624                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13625         fi
13626
13627         rm -f $DIR/$tfile
13628         echo "No pages locked after fsync"
13629
13630         return 0
13631 }
13632 run_test 118j "Simulate unrecoverable OST side error =========="
13633
13634 test_118k()
13635 {
13636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13637         remote_ost_nodsh && skip "remote OSTs with nodsh"
13638
13639         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13640         set_nodes_failloc "$(osts_nodes)" 0x20e
13641         test_mkdir $DIR/$tdir
13642
13643         for ((i=0;i<10;i++)); do
13644                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13645                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13646                 SLEEPPID=$!
13647                 sleep 0.500s
13648                 kill $SLEEPPID
13649                 wait $SLEEPPID
13650         done
13651
13652         set_nodes_failloc "$(osts_nodes)" 0
13653         rm -rf $DIR/$tdir
13654 }
13655 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13656
13657 test_118l() # LU-646
13658 {
13659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13660
13661         test_mkdir $DIR/$tdir
13662         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13663         rm -rf $DIR/$tdir
13664 }
13665 run_test 118l "fsync dir"
13666
13667 test_118m() # LU-3066
13668 {
13669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13670
13671         test_mkdir $DIR/$tdir
13672         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13673         rm -rf $DIR/$tdir
13674 }
13675 run_test 118m "fdatasync dir ========="
13676
13677 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13678
13679 test_118n()
13680 {
13681         local begin
13682         local end
13683
13684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13685         remote_ost_nodsh && skip "remote OSTs with nodsh"
13686
13687         # Sleep to avoid a cached response.
13688         #define OBD_STATFS_CACHE_SECONDS 1
13689         sleep 2
13690
13691         # Inject a 10 second delay in the OST_STATFS handler.
13692         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13693         set_nodes_failloc "$(osts_nodes)" 0x242
13694
13695         begin=$SECONDS
13696         stat --file-system $MOUNT > /dev/null
13697         end=$SECONDS
13698
13699         set_nodes_failloc "$(osts_nodes)" 0
13700
13701         if ((end - begin > 20)); then
13702             error "statfs took $((end - begin)) seconds, expected 10"
13703         fi
13704 }
13705 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13706
13707 test_119a() # bug 11737
13708 {
13709         BSIZE=$((512 * 1024))
13710         directio write $DIR/$tfile 0 1 $BSIZE
13711         # We ask to read two blocks, which is more than a file size.
13712         # directio will indicate an error when requested and actual
13713         # sizes aren't equeal (a normal situation in this case) and
13714         # print actual read amount.
13715         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13716         if [ "$NOB" != "$BSIZE" ]; then
13717                 error "read $NOB bytes instead of $BSIZE"
13718         fi
13719         rm -f $DIR/$tfile
13720 }
13721 run_test 119a "Short directIO read must return actual read amount"
13722
13723 test_119b() # bug 11737
13724 {
13725         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13726
13727         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13728         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13729         sync
13730         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13731                 error "direct read failed"
13732         rm -f $DIR/$tfile
13733 }
13734 run_test 119b "Sparse directIO read must return actual read amount"
13735
13736 test_119c() # bug 13099
13737 {
13738         BSIZE=1048576
13739         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13740         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13741         rm -f $DIR/$tfile
13742 }
13743 run_test 119c "Testing for direct read hitting hole"
13744
13745 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13746 # Maloo test history
13747
13748 test_119e()
13749 {
13750         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13751                 skip "Need server version at least 2.15.58"
13752         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13753
13754         local stripe_size=$((1024 * 1024)) #1 MiB
13755         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13756         local file_size=$((25 * stripe_size))
13757         local bsizes
13758
13759         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13760         stack_trap "rm -f $DIR/$tfile*"
13761
13762         # Just a bit bigger than the largest size in the test set below
13763         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13764                 error "buffered i/o to create file failed"
13765
13766         # trivial test of unaligned DIO
13767         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13768                 iflag=direct oflag=direct ||
13769                 error "trivial unaligned dio failed"
13770
13771         # Test of disabling unaligned DIO support
13772         $LCTL set_param llite.*.unaligned_dio=0
13773         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13774         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13775         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13776                 iflag=direct oflag=direct &&
13777                 error "unaligned dio succeeded when disabled"
13778         $LCTL set_param llite.*.unaligned_dio=1
13779
13780         # Clean up before next part of test
13781         rm -f $DIR/$tfile.2
13782
13783         if zfs_or_rotational; then
13784                 # DIO on ZFS can take up to 2 seconds per IO
13785                 # rotational is better, but still slow.
13786                 # Limit testing on those media to larger sizes
13787                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13788                         $((stripe_size + 1024))"
13789         else
13790                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13791                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13792                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13793                         $((stripe_size - 1)) $stripe_size \
13794                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13795                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13796         fi
13797
13798         for bs in $bsizes; do
13799                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13800                 echo "Read/write with DIO at size $bs"
13801                 # Read and write with DIO from source to dest
13802                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13803                         iflag=direct oflag=direct ||
13804                         error "dio failed"
13805
13806                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13807                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13808                         error "size incorrect, file copy read/write bsize: $bs"
13809                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13810                         error "files differ, bsize $bs"
13811                 rm -f $DIR/$tfile.2
13812         done
13813 }
13814 run_test 119e "Basic tests of dio read and write at various sizes"
13815
13816 test_119f()
13817 {
13818         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13819
13820         local stripe_size=$((1024 * 1024)) #1 MiB
13821         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13822         local file_size=$((25 * stripe_size))
13823         local bsizes
13824
13825         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13826         stack_trap "rm -f $DIR/$tfile*"
13827
13828         # Just a bit bigger than the largest size in the test set below
13829         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13830                 error "buffered i/o to create file failed"
13831
13832         if zfs_or_rotational; then
13833                 # DIO on ZFS can take up to 2 seconds per IO
13834                 # rotational is better, but still slow.
13835                 # Limit testing on those media to larger sizes
13836                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13837                         $((stripe_size + 1024))"
13838         else
13839                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13840                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13841                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13842                         $((stripe_size - 1)) $stripe_size \
13843                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13844                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13845         fi
13846
13847         for bs in $bsizes; do
13848                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13849                 # Read and write with DIO from source to dest in two
13850                 # threads - should give correct copy of file
13851
13852                 echo "bs: $bs"
13853                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13854                         oflag=direct conv=notrunc &
13855                 pid_dio1=$!
13856                 # Note block size is different here for a more interesting race
13857                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13858                         iflag=direct oflag=direct conv=notrunc &
13859                 pid_dio2=$!
13860                 wait $pid_dio1
13861                 rc1=$?
13862                 wait $pid_dio2
13863                 rc2=$?
13864                 if (( rc1 != 0 )); then
13865                         error "dio copy 1 w/bsize $bs failed: $rc1"
13866                 fi
13867                 if (( rc2 != 0 )); then
13868                         error "dio copy 2 w/bsize $bs failed: $rc2"
13869                 fi
13870
13871
13872                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13873                         error "size incorrect, file copy read/write bsize: $bs"
13874                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13875                         error "files differ, bsize $bs"
13876                 rm -f $DIR/$tfile.2
13877         done
13878 }
13879 run_test 119f "dio vs dio race"
13880
13881 test_119g()
13882 {
13883         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13884
13885         local stripe_size=$((1024 * 1024)) #1 MiB
13886         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13887         local file_size=$((25 * stripe_size))
13888         local bsizes
13889
13890         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13891         stack_trap "rm -f $DIR/$tfile*"
13892
13893         # Just a bit bigger than the largest size in the test set below
13894         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13895                 error "buffered i/o to create file failed"
13896
13897         if zfs_or_rotational; then
13898                 # DIO on ZFS can take up to 2 seconds per IO
13899                 # rotational is better, but still slow.
13900                 # Limit testing on those media to larger sizes
13901                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13902                         $((stripe_size + 1024))"
13903         else
13904                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13905                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13906                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13907                         $((stripe_size - 1)) $stripe_size \
13908                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13909                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13910         fi
13911
13912         for bs in $bsizes; do
13913                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13914                 echo "bs: $bs"
13915                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13916                         oflag=direct conv=notrunc &
13917                 pid_dio1=$!
13918                 # Buffered I/O with similar but not the same block size
13919                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13920                 pid_bio2=$!
13921                 wait $pid_dio1
13922                 rc1=$?
13923                 wait $pid_bio2
13924                 rc2=$?
13925                 if (( rc1 != 0 )); then
13926                         error "dio copy 1 w/bsize $bs failed: $rc1"
13927                 fi
13928                 if (( rc2 != 0 )); then
13929                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13930                 fi
13931
13932                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13933                         error "size incorrect"
13934                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13935                         error "files differ, bsize $bs"
13936                 rm -f $DIR/$tfile.2
13937         done
13938 }
13939 run_test 119g "dio vs buffered I/O race"
13940
13941 test_119h()
13942 {
13943         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13944
13945         local stripe_size=$((1024 * 1024)) #1 MiB
13946         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13947         local file_size=$((25 * stripe_size))
13948         local bsizes
13949
13950         stack_trap "rm -f $DIR/$tfile.*"
13951
13952         if zfs_or_rotational; then
13953                 # DIO on ZFS can take up to 2 seconds per IO
13954                 # rotational is better, but still slow.
13955                 # Limit testing on those media to larger sizes
13956                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13957                         $((stripe_size + 1024))"
13958         else
13959                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13960                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13961                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13962                         $((stripe_size - 1)) $stripe_size \
13963                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13964                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13965         fi
13966
13967         for bs in $bsizes; do
13968                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13969                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13970                 echo "unaligned writes of blocksize: $bs"
13971                 # Write a file with unaligned DIO and regular DIO, and compare
13972                 # them
13973                 # with 'u', multiop randomly unaligns the io from the buffer
13974                 $MULTIOP $DIR/$tfile.1 \
13975                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13976                         error "multiop memory unaligned write failed, $bs"
13977                 $MULTIOP $DIR/$tfile.2 \
13978                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13979                         error "multiop memory aligned write failed, $bs"
13980
13981                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13982                         error "files differ, bsize $bs"
13983                 rm -f $DIR/$tfile.*
13984         done
13985
13986         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13987         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13988                 error "dd to create source file for read failed"
13989
13990         # Just a few quick tests to make sure unaligned DIO reads don't crash
13991         for bs in $bsizes; do
13992
13993                 echo "unaligned reads of blocksize: $bs"
13994                 # with 'u', multiop randomly unaligns the io from the buffer
13995                 $MULTIOP $DIR/$tfile.1 \
13996                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13997                         error "multiop memory unaligned read failed, $bs"
13998
13999         done
14000         rm -f $DIR/$tfile*
14001 }
14002 run_test 119h "basic tests of memory unaligned dio"
14003
14004 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14005 test_119i()
14006 {
14007         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14008         which aiocp || skip_env "no aiocp installed"
14009
14010         local stripe_size=$((1024 * 1024)) #1 MiB
14011         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14012         local file_size=$((25 * stripe_size))
14013         local bsizes
14014
14015         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14016         stack_trap "rm -f $DIR/$tfile.*"
14017
14018         # Just a bit bigger than the largest size in the test set below
14019         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14020                 error "buffered i/o to create file failed"
14021
14022         if zfs_or_rotational; then
14023                 # DIO on ZFS can take up to 2 seconds per IO
14024                 # rotational is better, but still slow.
14025                 # Limit testing on those media to larger sizes
14026                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14027                         $((stripe_size + 1024))"
14028         else
14029                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14030                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14031                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14032                         $((stripe_size - 1)) $stripe_size \
14033                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14034                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14035         fi
14036
14037         # Do page aligned and NOT page aligned AIO
14038         for align in 8 512 $((PAGE_SIZE)); do
14039         # Deliberately includes a few aligned sizes
14040         for bs in $bsizes; do
14041                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14042
14043                 echo "bs: $bs, align: $align, file_size $file_size"
14044                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14045                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14046                         error "unaligned aio failed, bs: $bs, align: $align"
14047
14048                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14049                         error "size incorrect"
14050                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14051                         error "files differ"
14052                 rm -f $DIR/$tfile.2
14053         done
14054         done
14055 }
14056 run_test 119i "test unaligned aio at varying sizes"
14057
14058 test_119j()
14059 {
14060         (( $LINUX_VERSION_CODE > $(version_code 4.5.0) )) ||
14061                 skip "needs kernel > 4.5.0 for ki_flags support"
14062
14063         local rpcs
14064         dd if=/dev/urandom of=$DIR/$tfile bs=8 count=1 || error "(0) dd failed"
14065         sync
14066         $LCTL set_param -n osc.*.rpc_stats=0
14067         # Read from page cache, does not generate an rpc
14068         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(1) dd failed"
14069         $LCTL get_param osc.*.rpc_stats
14070         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14071                 sed -n '/pages per rpc/,/^$/p' |
14072                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14073                 END { print reads,writes }'))
14074         [[ ${rpcs[0]} == 0 ]] ||
14075                 error "(3) ${rpcs[0]} != 0 read RPCs"
14076
14077         # Test hybrid IO read
14078         # Force next BIO as DIO
14079         # This forces an RPC to the server
14080         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14081         $LCTL set_param fail_loc=0x1429
14082         dd if=$DIR/$tfile of=/dev/null bs=8 count=1 || error "(4) dd failed"
14083         $LCTL get_param osc.*.rpc_stats
14084         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14085                 sed -n '/pages per rpc/,/^$/p' |
14086                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14087                 END { print reads,writes }'))
14088         [[ ${rpcs[0]} == 1 ]] ||
14089                 error "(5) ${rpcs[0]} != 1 read RPCs"
14090
14091         # Test hybrid IO write
14092         #define OBD_FAIL_LLITE_FORCE_BIO_AS_DIO 0x1429
14093         $LCTL set_param fail_loc=0x1429
14094         #NB: We do not check for 0 write RPCs in the BIO case because that
14095         # would make the test racey vs cache flushing
14096         # but the DIO case is guaranteed to generate 1 write RPC
14097         dd if=/dev/zero of=$DIR/$tfile bs=8 count=1 || error "(6) dd failed"
14098         $LCTL get_param osc.*.rpc_stats
14099         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
14100                 sed -n '/pages per rpc/,/^$/p' |
14101                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
14102                 END { print reads,writes }'))
14103         [[ ${rpcs[1]} == 1 ]] ||
14104                 error "(7) ${rpcs[0]} != 1 read RPCs"
14105 }
14106 run_test 119j "basic tests of hybrid IO switching"
14107
14108 test_120a() {
14109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14110         remote_mds_nodsh && skip "remote MDS with nodsh"
14111         test_mkdir -i0 -c1 $DIR/$tdir
14112         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14113                 skip_env "no early lock cancel on server"
14114
14115         lru_resize_disable mdc
14116         lru_resize_disable osc
14117         cancel_lru_locks mdc
14118         # asynchronous object destroy at MDT could cause bl ast to client
14119         cancel_lru_locks osc
14120
14121         stat $DIR/$tdir > /dev/null
14122         can1=$(do_facet mds1 \
14123                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14124                awk '/ldlm_cancel/ {print $2}')
14125         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14126                awk '/ldlm_bl_callback/ {print $2}')
14127         test_mkdir -i0 -c1 $DIR/$tdir/d1
14128         can2=$(do_facet mds1 \
14129                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14130                awk '/ldlm_cancel/ {print $2}')
14131         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14132                awk '/ldlm_bl_callback/ {print $2}')
14133         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14134         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14135         lru_resize_enable mdc
14136         lru_resize_enable osc
14137 }
14138 run_test 120a "Early Lock Cancel: mkdir test"
14139
14140 test_120b() {
14141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14142         remote_mds_nodsh && skip "remote MDS with nodsh"
14143         test_mkdir $DIR/$tdir
14144         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14145                 skip_env "no early lock cancel on server"
14146
14147         lru_resize_disable mdc
14148         lru_resize_disable osc
14149         cancel_lru_locks mdc
14150         stat $DIR/$tdir > /dev/null
14151         can1=$(do_facet $SINGLEMDS \
14152                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14153                awk '/ldlm_cancel/ {print $2}')
14154         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14155                awk '/ldlm_bl_callback/ {print $2}')
14156         touch $DIR/$tdir/f1
14157         can2=$(do_facet $SINGLEMDS \
14158                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14159                awk '/ldlm_cancel/ {print $2}')
14160         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14161                awk '/ldlm_bl_callback/ {print $2}')
14162         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14163         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14164         lru_resize_enable mdc
14165         lru_resize_enable osc
14166 }
14167 run_test 120b "Early Lock Cancel: create test"
14168
14169 test_120c() {
14170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14171         remote_mds_nodsh && skip "remote MDS with nodsh"
14172         test_mkdir -i0 -c1 $DIR/$tdir
14173         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14174                 skip "no early lock cancel on server"
14175
14176         lru_resize_disable mdc
14177         lru_resize_disable osc
14178         test_mkdir -i0 -c1 $DIR/$tdir/d1
14179         test_mkdir -i0 -c1 $DIR/$tdir/d2
14180         touch $DIR/$tdir/d1/f1
14181         cancel_lru_locks mdc
14182         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14183         can1=$(do_facet mds1 \
14184                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14185                awk '/ldlm_cancel/ {print $2}')
14186         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14187                awk '/ldlm_bl_callback/ {print $2}')
14188         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14189         can2=$(do_facet mds1 \
14190                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14191                awk '/ldlm_cancel/ {print $2}')
14192         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14193                awk '/ldlm_bl_callback/ {print $2}')
14194         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14195         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14196         lru_resize_enable mdc
14197         lru_resize_enable osc
14198 }
14199 run_test 120c "Early Lock Cancel: link test"
14200
14201 test_120d() {
14202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14203         remote_mds_nodsh && skip "remote MDS with nodsh"
14204         test_mkdir -i0 -c1 $DIR/$tdir
14205         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14206                 skip_env "no early lock cancel on server"
14207
14208         lru_resize_disable mdc
14209         lru_resize_disable osc
14210         touch $DIR/$tdir
14211         cancel_lru_locks mdc
14212         stat $DIR/$tdir > /dev/null
14213         can1=$(do_facet mds1 \
14214                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14215                awk '/ldlm_cancel/ {print $2}')
14216         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14217                awk '/ldlm_bl_callback/ {print $2}')
14218         chmod a+x $DIR/$tdir
14219         can2=$(do_facet mds1 \
14220                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14221                awk '/ldlm_cancel/ {print $2}')
14222         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14223                awk '/ldlm_bl_callback/ {print $2}')
14224         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14225         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14226         lru_resize_enable mdc
14227         lru_resize_enable osc
14228 }
14229 run_test 120d "Early Lock Cancel: setattr test"
14230
14231 test_120e() {
14232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14233         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14234                 skip_env "no early lock cancel on server"
14235         remote_mds_nodsh && skip "remote MDS with nodsh"
14236
14237         local dlmtrace_set=false
14238
14239         test_mkdir -i0 -c1 $DIR/$tdir
14240         lru_resize_disable mdc
14241         lru_resize_disable osc
14242         ! $LCTL get_param debug | grep -q dlmtrace &&
14243                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14244         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14245         cancel_lru_locks mdc
14246         cancel_lru_locks osc
14247         dd if=$DIR/$tdir/f1 of=/dev/null
14248         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14249         # XXX client can not do early lock cancel of OST lock
14250         # during unlink (LU-4206), so cancel osc lock now.
14251         sleep 2
14252         cancel_lru_locks osc
14253         can1=$(do_facet mds1 \
14254                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14255                awk '/ldlm_cancel/ {print $2}')
14256         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14257                awk '/ldlm_bl_callback/ {print $2}')
14258         unlink $DIR/$tdir/f1
14259         sleep 5
14260         can2=$(do_facet mds1 \
14261                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14262                awk '/ldlm_cancel/ {print $2}')
14263         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14264                awk '/ldlm_bl_callback/ {print $2}')
14265         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14266                 $LCTL dk $TMP/cancel.debug.txt
14267         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14268                 $LCTL dk $TMP/blocking.debug.txt
14269         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14270         lru_resize_enable mdc
14271         lru_resize_enable osc
14272 }
14273 run_test 120e "Early Lock Cancel: unlink test"
14274
14275 test_120f() {
14276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14277         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14278                 skip_env "no early lock cancel on server"
14279         remote_mds_nodsh && skip "remote MDS with nodsh"
14280
14281         test_mkdir -i0 -c1 $DIR/$tdir
14282         lru_resize_disable mdc
14283         lru_resize_disable osc
14284         test_mkdir -i0 -c1 $DIR/$tdir/d1
14285         test_mkdir -i0 -c1 $DIR/$tdir/d2
14286         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14287         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14288         cancel_lru_locks mdc
14289         cancel_lru_locks osc
14290         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14291         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14292         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14293         # XXX client can not do early lock cancel of OST lock
14294         # during rename (LU-4206), so cancel osc lock now.
14295         sleep 2
14296         cancel_lru_locks osc
14297         can1=$(do_facet mds1 \
14298                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14299                awk '/ldlm_cancel/ {print $2}')
14300         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14301                awk '/ldlm_bl_callback/ {print $2}')
14302         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14303         sleep 5
14304         can2=$(do_facet mds1 \
14305                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14306                awk '/ldlm_cancel/ {print $2}')
14307         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14308                awk '/ldlm_bl_callback/ {print $2}')
14309         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14310         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14311         lru_resize_enable mdc
14312         lru_resize_enable osc
14313 }
14314 run_test 120f "Early Lock Cancel: rename test"
14315
14316 test_120g() {
14317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14318         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14319                 skip_env "no early lock cancel on server"
14320         remote_mds_nodsh && skip "remote MDS with nodsh"
14321
14322         lru_resize_disable mdc
14323         lru_resize_disable osc
14324         count=10000
14325         echo create $count files
14326         test_mkdir $DIR/$tdir
14327         cancel_lru_locks mdc
14328         cancel_lru_locks osc
14329         t0=$(date +%s)
14330
14331         can0=$(do_facet $SINGLEMDS \
14332                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14333                awk '/ldlm_cancel/ {print $2}')
14334         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14335                awk '/ldlm_bl_callback/ {print $2}')
14336         createmany -o $DIR/$tdir/f $count
14337         sync
14338         can1=$(do_facet $SINGLEMDS \
14339                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14340                awk '/ldlm_cancel/ {print $2}')
14341         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14342                awk '/ldlm_bl_callback/ {print $2}')
14343         t1=$(date +%s)
14344         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14345         echo rm $count files
14346         rm -r $DIR/$tdir
14347         sync
14348         can2=$(do_facet $SINGLEMDS \
14349                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14350                awk '/ldlm_cancel/ {print $2}')
14351         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14352                awk '/ldlm_bl_callback/ {print $2}')
14353         t2=$(date +%s)
14354         echo total: $count removes in $((t2-t1))
14355         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14356         sleep 2
14357         # wait for commitment of removal
14358         lru_resize_enable mdc
14359         lru_resize_enable osc
14360 }
14361 run_test 120g "Early Lock Cancel: performance test"
14362
14363 test_121() { #bug #10589
14364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14365
14366         rm -rf $DIR/$tfile
14367         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14368 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14369         lctl set_param fail_loc=0x310
14370         cancel_lru_locks osc > /dev/null
14371         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14372         lctl set_param fail_loc=0
14373         [[ $reads -eq $writes ]] ||
14374                 error "read $reads blocks, must be $writes blocks"
14375 }
14376 run_test 121 "read cancel race ========="
14377
14378 test_123a_base() { # was test 123, statahead(bug 11401)
14379         local lsx="$1"
14380
14381         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14382
14383         SLOWOK=0
14384         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14385                 log "testing UP system. Performance may be lower than expected."
14386                 SLOWOK=1
14387         fi
14388         running_in_vm && SLOWOK=1
14389
14390         $LCTL set_param mdc.*.batch_stats=0
14391
14392         rm -rf $DIR/$tdir
14393         test_mkdir $DIR/$tdir
14394         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14395         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14396         MULT=10
14397         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14398                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14399
14400                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14401                 lctl set_param -n llite.*.statahead_max 0
14402                 lctl get_param llite.*.statahead_max
14403                 cancel_lru_locks mdc
14404                 cancel_lru_locks osc
14405                 stime=$(date +%s)
14406                 time $lsx $DIR/$tdir | wc -l
14407                 etime=$(date +%s)
14408                 delta=$((etime - stime))
14409                 log "$lsx $i files without statahead: $delta sec"
14410                 lctl set_param llite.*.statahead_max=$max
14411
14412                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14413                          awk '/statahead.wrong:/ { print $NF }')
14414                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14415                 cancel_lru_locks mdc
14416                 cancel_lru_locks osc
14417                 stime=$(date +%s)
14418                 time $lsx $DIR/$tdir | wc -l
14419                 etime=$(date +%s)
14420                 delta_sa=$((etime - stime))
14421                 log "$lsx $i files with statahead: $delta_sa sec"
14422                 lctl get_param -n llite.*.statahead_stats
14423                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14424                          awk '/statahead.wrong:/ { print $NF }')
14425
14426                 [[ $swrong -lt $ewrong ]] &&
14427                         log "statahead was stopped, maybe too many locks held!"
14428                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14429
14430                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14431                         max=$(lctl get_param -n llite.*.statahead_max |
14432                                 head -n 1)
14433                         lctl set_param -n llite.*.statahead_max 0
14434                         lctl get_param llite.*.statahead_max
14435                         cancel_lru_locks mdc
14436                         cancel_lru_locks osc
14437                         stime=$(date +%s)
14438                         time $lsx $DIR/$tdir | wc -l
14439                         etime=$(date +%s)
14440                         delta=$((etime - stime))
14441                         log "$lsx $i files again without statahead: $delta sec"
14442                         lctl set_param llite.*.statahead_max=$max
14443                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14444                                 if [ $SLOWOK -eq 0 ]; then
14445                                         error "$lsx $i files is slower with statahead!"
14446                                 else
14447                                         log "$lsx $i files is slower with statahead!"
14448                                 fi
14449                                 break
14450                         fi
14451                 fi
14452
14453                 [ $delta -gt 20 ] && break
14454                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14455                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14456         done
14457         log "$lsx done"
14458
14459         stime=$(date +%s)
14460         rm -r $DIR/$tdir
14461         sync
14462         etime=$(date +%s)
14463         delta=$((etime - stime))
14464         log "rm -r $DIR/$tdir/: $delta seconds"
14465         log "rm done"
14466         lctl get_param -n llite.*.statahead_stats
14467         $LCTL get_param mdc.*.batch_stats
14468 }
14469
14470 test_123aa() {
14471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14472
14473         test_123a_base "ls -l"
14474 }
14475 run_test 123aa "verify statahead work"
14476
14477 test_123ab() {
14478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14479
14480         statx_supported || skip_env "Test must be statx() syscall supported"
14481
14482         test_123a_base "$STATX -l"
14483 }
14484 run_test 123ab "verify statahead work by using statx"
14485
14486 test_123ac() {
14487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14488
14489         statx_supported || skip_env "Test must be statx() syscall supported"
14490
14491         local rpcs_before
14492         local rpcs_after
14493         local agl_before
14494         local agl_after
14495
14496         cancel_lru_locks $OSC
14497         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14498         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14499                      awk '/agl.total:/ { print $NF }')
14500         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14501         test_123a_base "$STATX --cached=always -D"
14502         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14503                     awk '/agl.total:/ { print $NF }')
14504         [ $agl_before -eq $agl_after ] ||
14505                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14506         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14507         [ $rpcs_after -eq $rpcs_before ] ||
14508                 error "$STATX should not send glimpse RPCs to $OSC"
14509 }
14510 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14511
14512 test_batch_statahead() {
14513         local max=$1
14514         local batch_max=$2
14515         local num=10000
14516         local batch_rpcs
14517         local unbatch_rpcs
14518         local hit_total
14519
14520         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14521         $LCTL set_param mdc.*.batch_stats=0
14522         $LCTL set_param llite.*.statahead_max=$max
14523         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14524         # Verify that batched statahead is faster than one without statahead
14525         test_123a_base "ls -l"
14526
14527         stack_trap "rm -rf $DIR/$tdir" EXIT
14528         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14529         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14530
14531         # unbatched statahead
14532         $LCTL set_param llite.*.statahead_batch_max=0
14533         $LCTL set_param llite.*.statahead_stats=clear
14534         $LCTL set_param mdc.*.stats=clear
14535         cancel_lru_locks mdc
14536         cancel_lru_locks osc
14537         time ls -l $DIR/$tdir | wc -l
14538         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14539         wait_update_facet client "pgrep ll_sa" "" 35 ||
14540                 error "ll_sa thread is still running"
14541         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14542                     awk '/hit.total:/ { print $NF }')
14543         # hit ratio should be larger than 75% (7500).
14544         (( $hit_total > 7500 )) ||
14545                 error "unbatched statahead hit count ($hit_total) is too low"
14546
14547         # batched statahead
14548         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14549         $LCTL set_param llite.*.statahead_stats=clear
14550         $LCTL set_param mdc.*.batch_stats=clear
14551         $LCTL set_param mdc.*.stats=clear
14552         cancel_lru_locks mdc
14553         cancel_lru_locks osc
14554         time ls -l $DIR/$tdir | wc -l
14555         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14556         # wait for statahead thread to quit and update statahead stats
14557         wait_update_facet client "pgrep ll_sa" "" 35 ||
14558                 error "ll_sa thread is still running"
14559         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14560                     awk '/hit.total:/ { print $NF }')
14561         # hit ratio should be larger than 75% (7500).
14562         (( $hit_total > 7500 )) ||
14563                 error "batched statahead hit count ($hit_total) is too low"
14564
14565         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14566         (( $unbatch_rpcs > $batch_rpcs )) ||
14567                 error "batched statahead does not reduce RPC count"
14568         $LCTL get_param mdc.*.batch_stats
14569 }
14570
14571 test_123ad() {
14572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14573
14574         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14575                 skip "Need server version at least 2.15.53"
14576
14577         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14578                 skip "Server does not support batch RPC"
14579
14580         local max
14581         local batch_max
14582
14583         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14584         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14585
14586         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14587         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14588
14589         test_batch_statahead 32 32
14590         test_batch_statahead 2048 256
14591 }
14592 run_test 123ad "Verify batching statahead works correctly"
14593
14594 test_123b () { # statahead(bug 15027)
14595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14596
14597         test_mkdir $DIR/$tdir
14598         createmany -o $DIR/$tdir/$tfile-%d 1000
14599
14600         cancel_lru_locks mdc
14601         cancel_lru_locks osc
14602
14603 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14604         lctl set_param fail_loc=0x80000803
14605         ls -lR $DIR/$tdir > /dev/null
14606         log "ls done"
14607         lctl set_param fail_loc=0x0
14608         lctl get_param -n llite.*.statahead_stats
14609         rm -r $DIR/$tdir
14610         sync
14611
14612 }
14613 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14614
14615 test_123c() {
14616         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14617
14618         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14619         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14620         touch $DIR/$tdir.1/{1..3}
14621         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14622
14623         remount_client $MOUNT
14624
14625         $MULTIOP $DIR/$tdir.0 Q
14626
14627         # let statahead to complete
14628         ls -l $DIR/$tdir.0 > /dev/null
14629
14630         testid=$(echo $TESTNAME | tr '_' ' ')
14631         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14632                 error "statahead warning" || true
14633 }
14634 run_test 123c "Can not initialize inode warning on DNE statahead"
14635
14636 test_123d() {
14637         local num=100
14638         local swrong
14639         local ewrong
14640
14641         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14642         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14643                 error "setdirstripe $DIR/$tdir failed"
14644         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14645         remount_client $MOUNT
14646         $LCTL get_param llite.*.statahead_max
14647         $LCTL set_param llite.*.statahead_stats=0 ||
14648                 error "clear statahead_stats failed"
14649         swrong=$(lctl get_param -n llite.*.statahead_stats |
14650                  awk '/statahead.wrong:/ { print $NF }')
14651         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14652         # wait for statahead thread finished to update hit/miss stats.
14653         sleep 1
14654         $LCTL get_param -n llite.*.statahead_stats
14655         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14656                  awk '/statahead.wrong:/ { print $NF }')
14657         (( $swrong == $ewrong )) ||
14658                 log "statahead was stopped, maybe too many locks held!"
14659 }
14660 run_test 123d "Statahead on striped directories works correctly"
14661
14662 test_123e() {
14663         local max
14664         local batch_max
14665         local dir=$DIR/$tdir
14666
14667         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14668                 skip "Server does not support batch RPC"
14669
14670         mkdir $dir || error "mkdir $dir failed"
14671         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14672         stack_trap "rm -rf $dir"
14673
14674         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14675
14676         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14677         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14678         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14679         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14680
14681         $LCTL set_param llite.*.statahead_max=2048
14682         $LCTL set_param llite.*.statahead_batch_max=1024
14683
14684         ls -l $dir
14685         $LCTL get_param mdc.*.batch_stats
14686         $LCTL get_param llite.*.statahead_*
14687 }
14688 run_test 123e "statahead with large wide striping"
14689
14690 test_123f() {
14691         local max
14692         local batch_max
14693         local dir=$DIR/$tdir
14694
14695         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14696                 skip "Server does not support batch RPC"
14697
14698         mkdir $dir || error "mkdir $dir failed"
14699         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14700         stack_trap "rm -rf $dir"
14701
14702         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14703
14704         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14705         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14706
14707         $LCTL set_param llite.*.statahead_max=64
14708         $LCTL set_param llite.*.statahead_batch_max=64
14709
14710         ls -l $dir
14711         lctl get_param mdc.*.batch_stats
14712         lctl get_param llite.*.statahead_*
14713
14714         $LCTL set_param llite.*.statahead_max=$max
14715         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14716 }
14717 run_test 123f "Retry mechanism with large wide striping files"
14718
14719 test_123g() {
14720         local dir=$DIR/$tdir
14721         local num=1000
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 "failed to mkdir $dir"
14727         createmany -o $dir/$tfile $num || error "failed creatmany files"
14728         cancel_lru_locks mdc
14729         cancel_lru_locks osc
14730
14731         $LCTL set_param llite.*.statahead_stats=clear
14732         $LCTL set_param mdc.*.batch_stats=clear
14733         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14734                 error "aheadmany $dir with $tfile failed"
14735         wait_update_facet client "pgrep ll_sa" "" 35 ||
14736                 error "ll_sa thread is still running"
14737         $LCTL get_param -n llite.*.statahead_stats
14738         $LCTL get_param -n mdc.*.batch_stats
14739
14740         local count
14741
14742         count=$($LCTL get_param -n llite.*.statahead_stats |
14743                 awk '/hit.total:/ {print $2}')
14744         echo "Hit total: $count"
14745         # Hit ratio should be >= 75%
14746         (( $count > num * 75 / 100 )) ||
14747                 error "hit total $count is be > 75% of $num"
14748 }
14749 run_test 123g "Test for stat-ahead advise"
14750
14751 test_123h_base() {
14752         local dir=$DIR/$tdir
14753         local cmd="touch $dir/$tfile.{$1}"
14754         local fcnt=$2
14755
14756         stack_trap "rm -rf $dir"
14757         mkdir -p $dir || error "failed to mkdir $dir"
14758         eval $cmd
14759
14760         cancel_lru_locks mdc
14761         $LCTL set_param llite.*.statahead_stats=clear
14762         $LCTL set_param mdc.*.batch_stats=0
14763         $LCTL set_param llite.*.statahead_max=1024
14764         $LCTL set_param llite.*.statahead_batch_max=1024
14765         lctl get_param -n llite.*.statahead_stats
14766         du -a $dir > /dev/null
14767         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14768         wait_update_facet client "pgrep ll_sa" "" 35 ||
14769                 error "ll_sa statahead thread does not quit in 35s"
14770         $LCTL get_param -n llite.*.statahead_stats
14771         $LCTL get_param -n mdc.*.batch_stats
14772
14773         local count=$($LCTL get_param -n llite.*.statahead_stats |
14774                         awk '/fname.total:/ {print $2}')
14775
14776         [ $count == 1 ] || error "File name pattern statahead not trigger"
14777         count=$($LCTL get_param -n llite.*.statahead_stats |
14778                 awk '/hit.total:/ {print $2}')
14779         # Hit ratio should be >= 75%
14780         (( $count > fcnt * 75 / 100 )) ||
14781                 error "hit total is too low: $count"
14782         rm -rf $dir || error "rm -rf $dir failed"
14783 }
14784
14785 test_123h() {
14786         local max
14787         local batch_max
14788         local enabled
14789
14790         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14791                 skip "Server does not support batch RPC"
14792
14793         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14794         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14795         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14796         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14797         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14798         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14799
14800         $LCTL set_param llite.*.enable_statahead_fname=1
14801
14802         echo "Scan a directory with number regularized fname"
14803         test_123h_base "0..10000" 10000
14804
14805         echo "Scan a directory with zeroed padding number regularized fname"
14806         test_123h_base "000000..010000" 10000
14807 }
14808 run_test 123h "Verify statahead work with the fname pattern via du"
14809
14810 test_123i_base() {
14811         local fmt=$1
14812         local iocmd=$2
14813         local dir=$DIR/$tdir
14814         local cmd="createmany -m $fmt"
14815
14816         echo "Command:"
14817         echo "- $cmd"
14818         echo "- $iocmd"
14819         stack_trap "unlinkmany $fmt"
14820         mkdir -p $dir || error "failed to mkdir $dir"
14821         eval $cmd
14822
14823         cancel_lru_locks mdc
14824         $LCTL set_param llite.*.statahead_stats=clear
14825         $LCTL set_param mdc.*.batch_stats=0
14826
14827         echo "statahead_stats (Pre):"
14828         lctl get_param -n llite.*.statahead_stats
14829         eval $iocmd || error "$iocmd failed"
14830         echo "statahead_stats (Post):"
14831         $LCTL get_param -n llite.*.statahead_stats
14832         $LCTL get_param -n mdc.*.batch_stats
14833
14834         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14835         wait_update_facet client "pgrep ll_sa" "" 35 ||
14836                 error "ll_sa statahead thread does not quit in 35s"
14837         $LCTL get_param -n llite.*.statahead_stats
14838         $LCTL get_param -n mdc.*.batch_stats
14839
14840         local count=$($LCTL get_param -n llite.*.statahead_stats |
14841                         awk '/fname.total:/ {print $2}')
14842
14843         [ $count == 1 ] || error "File name pattern statahead not trigger"
14844         count=$($LCTL get_param -n llite.*.statahead_stats |
14845                 awk '/hit.total:/ {print $2}')
14846         # Hit ratio should be >= 75%
14847         (( $count > 750 )) || error "hit total is too low: $count"
14848 }
14849
14850 test_123i() {
14851         local dir=$DIR/$tdir
14852         local cnt=1000
14853         local max
14854         local batch_max
14855         local enabled
14856         local min
14857
14858         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14859                 skip "Server does not support batch RPC"
14860
14861         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14862         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14863         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14864         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14865         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14866         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14867         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14868         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14869         $LCTL set_param llite.*.statahead_max=1024
14870         $LCTL set_param llite.*.statahead_batch_max=32
14871         $LCTL set_param llite.*.statahead_min=64
14872         $LCTL set_param llite.*.enable_statahead_fname=1
14873
14874         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14875         test_123i_base "$dir/$tfile $cnt" \
14876                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14877 }
14878 run_test 123i "Verify statahead work with the fname indexing pattern"
14879
14880 test_124a() {
14881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14882         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14883                 skip_env "no lru resize on server"
14884
14885         local NR=2000
14886
14887         test_mkdir $DIR/$tdir
14888
14889         log "create $NR files at $DIR/$tdir"
14890         createmany -o $DIR/$tdir/f $NR ||
14891                 error "failed to create $NR files in $DIR/$tdir"
14892
14893         cancel_lru_locks mdc
14894         ls -l $DIR/$tdir > /dev/null
14895
14896         local NSDIR=""
14897         local LRU_SIZE=0
14898         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14899                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14900                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14901                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14902                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14903                         log "NSDIR=$NSDIR"
14904                         log "NS=$(basename $NSDIR)"
14905                         break
14906                 fi
14907         done
14908
14909         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14910                 skip "Not enough cached locks created!"
14911         fi
14912         log "LRU=$LRU_SIZE"
14913
14914         local SLEEP=30
14915
14916         # We know that lru resize allows one client to hold $LIMIT locks
14917         # for 10h. After that locks begin to be killed by client.
14918         local MAX_HRS=10
14919         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14920         log "LIMIT=$LIMIT"
14921         if [ $LIMIT -lt $LRU_SIZE ]; then
14922                 skip "Limit is too small $LIMIT"
14923         fi
14924
14925         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14926         # killing locks. Some time was spent for creating locks. This means
14927         # that up to the moment of sleep finish we must have killed some of
14928         # them (10-100 locks). This depends on how fast ther were created.
14929         # Many of them were touched in almost the same moment and thus will
14930         # be killed in groups.
14931         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14932
14933         # Use $LRU_SIZE_B here to take into account real number of locks
14934         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14935         local LRU_SIZE_B=$LRU_SIZE
14936         log "LVF=$LVF"
14937         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14938         log "OLD_LVF=$OLD_LVF"
14939         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14940
14941         # Let's make sure that we really have some margin. Client checks
14942         # cached locks every 10 sec.
14943         SLEEP=$((SLEEP+20))
14944         log "Sleep ${SLEEP} sec"
14945         local SEC=0
14946         while ((SEC<$SLEEP)); do
14947                 echo -n "..."
14948                 sleep 5
14949                 SEC=$((SEC+5))
14950                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14951                 echo -n "$LRU_SIZE"
14952         done
14953         echo ""
14954         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14955         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14956
14957         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14958                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14959                 unlinkmany $DIR/$tdir/f $NR
14960                 return
14961         }
14962
14963         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14964         log "unlink $NR files at $DIR/$tdir"
14965         unlinkmany $DIR/$tdir/f $NR
14966 }
14967 run_test 124a "lru resize ======================================="
14968
14969 get_max_pool_limit()
14970 {
14971         local limit=$($LCTL get_param \
14972                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14973         local max=0
14974         for l in $limit; do
14975                 if [[ $l -gt $max ]]; then
14976                         max=$l
14977                 fi
14978         done
14979         echo $max
14980 }
14981
14982 test_124b() {
14983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14984         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14985                 skip_env "no lru resize on server"
14986
14987         LIMIT=$(get_max_pool_limit)
14988
14989         NR=$(($(default_lru_size)*20))
14990         if [[ $NR -gt $LIMIT ]]; then
14991                 log "Limit lock number by $LIMIT locks"
14992                 NR=$LIMIT
14993         fi
14994
14995         IFree=$(mdsrate_inodes_available)
14996         if [ $IFree -lt $NR ]; then
14997                 log "Limit lock number by $IFree inodes"
14998                 NR=$IFree
14999         fi
15000
15001         lru_resize_disable mdc
15002         test_mkdir -p $DIR/$tdir/disable_lru_resize
15003
15004         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
15005         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
15006         cancel_lru_locks mdc
15007         stime=`date +%s`
15008         PID=""
15009         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15010         PID="$PID $!"
15011         sleep 2
15012         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15013         PID="$PID $!"
15014         sleep 2
15015         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
15016         PID="$PID $!"
15017         wait $PID
15018         etime=`date +%s`
15019         nolruresize_delta=$((etime-stime))
15020         log "ls -la time: $nolruresize_delta seconds"
15021         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15022         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
15023
15024         lru_resize_enable mdc
15025         test_mkdir -p $DIR/$tdir/enable_lru_resize
15026
15027         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
15028         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
15029         cancel_lru_locks mdc
15030         stime=`date +%s`
15031         PID=""
15032         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15033         PID="$PID $!"
15034         sleep 2
15035         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15036         PID="$PID $!"
15037         sleep 2
15038         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15039         PID="$PID $!"
15040         wait $PID
15041         etime=`date +%s`
15042         lruresize_delta=$((etime-stime))
15043         log "ls -la time: $lruresize_delta seconds"
15044         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15045
15046         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15047                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15048         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15049                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15050         else
15051                 log "lru resize performs the same with no lru resize"
15052         fi
15053         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15054 }
15055 run_test 124b "lru resize (performance test) ======================="
15056
15057 test_124c() {
15058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15059         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15060                 skip_env "no lru resize on server"
15061
15062         # cache ununsed locks on client
15063         local nr=100
15064         cancel_lru_locks mdc
15065         test_mkdir $DIR/$tdir
15066         createmany -o $DIR/$tdir/f $nr ||
15067                 error "failed to create $nr files in $DIR/$tdir"
15068         ls -l $DIR/$tdir > /dev/null
15069
15070         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15071         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15072         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15073         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15074         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15075
15076         # set lru_max_age to 1 sec
15077         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15078         echo "sleep $((recalc_p * 2)) seconds..."
15079         sleep $((recalc_p * 2))
15080
15081         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15082         # restore lru_max_age
15083         $LCTL set_param -n $nsdir.lru_max_age $max_age
15084         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15085         unlinkmany $DIR/$tdir/f $nr
15086 }
15087 run_test 124c "LRUR cancel very aged locks"
15088
15089 test_124d() {
15090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15091         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15092                 skip_env "no lru resize on server"
15093
15094         # cache ununsed locks on client
15095         local nr=100
15096
15097         lru_resize_disable mdc
15098         stack_trap "lru_resize_enable mdc" EXIT
15099
15100         cancel_lru_locks mdc
15101
15102         # asynchronous object destroy at MDT could cause bl ast to client
15103         test_mkdir $DIR/$tdir
15104         createmany -o $DIR/$tdir/f $nr ||
15105                 error "failed to create $nr files in $DIR/$tdir"
15106         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15107
15108         ls -l $DIR/$tdir > /dev/null
15109
15110         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15111         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15112         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15113         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15114
15115         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15116
15117         # set lru_max_age to 1 sec
15118         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15119         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15120
15121         echo "sleep $((recalc_p * 2)) seconds..."
15122         sleep $((recalc_p * 2))
15123
15124         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15125
15126         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15127 }
15128 run_test 124d "cancel very aged locks if lru-resize disabled"
15129
15130 test_125() { # 13358
15131         $LCTL get_param -n llite.*.client_type | grep -q local ||
15132                 skip "must run as local client"
15133         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15134                 skip_env "must have acl enabled"
15135         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15136         id $USER0 || skip_env "missing user $USER0"
15137
15138         test_mkdir $DIR/$tdir
15139         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15140         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15141                 error "setfacl $DIR/$tdir failed"
15142         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15143 }
15144 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15145
15146 test_126() { # bug 12829/13455
15147         $GSS && skip_env "must run as gss disabled"
15148         $LCTL get_param -n llite.*.client_type | grep -q local ||
15149                 skip "must run as local client"
15150         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15151
15152         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15153         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15154         rm -f $DIR/$tfile
15155         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15156 }
15157 run_test 126 "check that the fsgid provided by the client is taken into account"
15158
15159 test_127a() { # bug 15521
15160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15161         local name count samp unit min max sum sumsq
15162         local tmpfile=$TMP/$tfile.tmp
15163
15164         # enable stats header if it is disabled
15165         $LCTL set_param enable_stats_header=1
15166
15167         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15168         echo "stats before reset"
15169         stack_trap "rm -f $tmpfile"
15170         local now=$(date +%s)
15171
15172         $LCTL get_param osc.*.stats | tee $tmpfile
15173
15174         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15175         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15176         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15177         local uptime=$(awk '{ print $1 }' /proc/uptime)
15178
15179         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15180         (( ${snapshot_time%\.*} >= $now - 5 &&
15181            ${snapshot_time%\.*} <= $now + 5 )) ||
15182                 error "snapshot_time=$snapshot_time != now=$now"
15183         # elapsed _should_ be from mount, but at least less than uptime
15184         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15185                 error "elapsed=$elapsed > uptime=$uptime"
15186         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15187            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15188                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15189
15190         $LCTL set_param osc.*.stats=0
15191         local reset=$(date +%s)
15192         local fsize=$((2048 * 1024))
15193
15194         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15195         cancel_lru_locks osc
15196         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15197
15198         now=$(date +%s)
15199         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15200         while read name count samp unit min max sum sumsq; do
15201                 [[ "$samp" == "samples" ]] || continue
15202
15203                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15204                 [ ! $min ] && error "Missing min value for $name proc entry"
15205                 eval $name=$count || error "Wrong proc format"
15206
15207                 case $name in
15208                 read_bytes|write_bytes)
15209                         [[ "$unit" =~ "bytes" ]] ||
15210                                 error "unit is not 'bytes': $unit"
15211                         (( $min >= 4096 )) || error "min is too small: $min"
15212                         (( $min <= $fsize )) || error "min is too big: $min"
15213                         (( $max >= 4096 )) || error "max is too small: $max"
15214                         (( $max <= $fsize )) || error "max is too big: $max"
15215                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15216                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15217                                 error "sumsquare is too small: $sumsq"
15218                         (( $sumsq <= $fsize * $fsize )) ||
15219                                 error "sumsquare is too big: $sumsq"
15220                         ;;
15221                 ost_read|ost_write)
15222                         [[ "$unit" =~ "usec" ]] ||
15223                                 error "unit is not 'usec': $unit"
15224                         ;;
15225                 *)      ;;
15226                 esac
15227         done < $tmpfile
15228
15229         #check that we actually got some stats
15230         [ "$read_bytes" ] || error "Missing read_bytes stats"
15231         [ "$write_bytes" ] || error "Missing write_bytes stats"
15232         [ "$read_bytes" != 0 ] || error "no read done"
15233         [ "$write_bytes" != 0 ] || error "no write done"
15234
15235         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15236         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15237         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15238
15239         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15240         (( ${snapshot_time%\.*} >= $now - 5 &&
15241            ${snapshot_time%\.*} <= $now + 5 )) ||
15242                 error "reset snapshot_time=$snapshot_time != now=$now"
15243         # elapsed should be from time of stats reset
15244         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15245            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15246                 error "reset elapsed=$elapsed > $now - $reset"
15247         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15248            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15249                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15250 }
15251 run_test 127a "verify the client stats are sane"
15252
15253 test_127b() { # bug LU-333
15254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15255         local name count samp unit min max sum sumsq
15256
15257         echo "stats before reset"
15258         $LCTL get_param llite.*.stats
15259         $LCTL set_param llite.*.stats=0
15260
15261         # perform 2 reads and writes so MAX is different from SUM.
15262         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15263         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15264         cancel_lru_locks osc
15265         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15266         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15267
15268         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15269         stack_trap "rm -f $TMP/$tfile.tmp"
15270         while read name count samp unit min max sum sumsq; do
15271                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15272                 eval $name=$count || error "Wrong proc format"
15273
15274                 case $name in
15275                 read_bytes|write_bytes)
15276                         [[ "$unit" =~ "bytes" ]] ||
15277                                 error "unit is not 'bytes': $unit"
15278                         (( $count == 2 )) || error "count is not 2: $count"
15279                         (( $min == $PAGE_SIZE )) ||
15280                                 error "min is not $PAGE_SIZE: $min"
15281                         (( $max == $PAGE_SIZE )) ||
15282                                 error "max is not $PAGE_SIZE: $max"
15283                         (( $sum == $PAGE_SIZE * 2 )) ||
15284                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15285                         ;;
15286                 read|write)
15287                         [[ "$unit" =~ "usec" ]] ||
15288                                 error "unit is not 'usec': $unit"
15289                         ;;
15290                 *)      ;;
15291                 esac
15292         done < $TMP/$tfile.tmp
15293
15294         #check that we actually got some stats
15295         [ "$read_bytes" ] || error "Missing read_bytes stats"
15296         [ "$write_bytes" ] || error "Missing write_bytes stats"
15297         [ "$read_bytes" != 0 ] || error "no read done"
15298         [ "$write_bytes" != 0 ] || error "no write done"
15299 }
15300 run_test 127b "verify the llite client stats are sane"
15301
15302 test_127c() { # LU-12394
15303         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15304         local size
15305         local bsize
15306         local reads
15307         local writes
15308         local count
15309
15310         $LCTL set_param llite.*.extents_stats=1
15311         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15312
15313         # Use two stripes so there is enough space in default config
15314         $LFS setstripe -c 2 $DIR/$tfile
15315
15316         # Extent stats start at 0-4K and go in power of two buckets
15317         # LL_HIST_START = 12 --> 2^12 = 4K
15318         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15319         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15320         # small configs
15321         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15322                 do
15323                 # Write and read, 2x each, second time at a non-zero offset
15324                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15325                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15326                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15327                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15328                 rm -f $DIR/$tfile
15329         done
15330
15331         $LCTL get_param llite.*.extents_stats
15332
15333         count=2
15334         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15335                 do
15336                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15337                                 grep -m 1 $bsize)
15338                 reads=$(echo $bucket | awk '{print $5}')
15339                 writes=$(echo $bucket | awk '{print $9}')
15340                 [ "$reads" -eq $count ] ||
15341                         error "$reads reads in < $bsize bucket, expect $count"
15342                 [ "$writes" -eq $count ] ||
15343                         error "$writes writes in < $bsize bucket, expect $count"
15344         done
15345
15346         # Test mmap write and read
15347         $LCTL set_param llite.*.extents_stats=c
15348         size=512
15349         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15350         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15351         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15352
15353         $LCTL get_param llite.*.extents_stats
15354
15355         count=$(((size*1024) / PAGE_SIZE))
15356
15357         bsize=$((2 * PAGE_SIZE / 1024))K
15358
15359         bucket=$($LCTL get_param -n llite.*.extents_stats |
15360                         grep -m 1 $bsize)
15361         reads=$(echo $bucket | awk '{print $5}')
15362         writes=$(echo $bucket | awk '{print $9}')
15363         # mmap writes fault in the page first, creating an additonal read
15364         [ "$reads" -eq $((2 * count)) ] ||
15365                 error "$reads reads in < $bsize bucket, expect $count"
15366         [ "$writes" -eq $count ] ||
15367                 error "$writes writes in < $bsize bucket, expect $count"
15368 }
15369 run_test 127c "test llite extent stats with regular & mmap i/o"
15370
15371 test_128() { # bug 15212
15372         touch $DIR/$tfile
15373         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15374                 find $DIR/$tfile
15375                 find $DIR/$tfile
15376         EOF
15377
15378         result=$(grep error $TMP/$tfile.log)
15379         rm -f $DIR/$tfile $TMP/$tfile.log
15380         [ -z "$result" ] ||
15381                 error "consecutive find's under interactive lfs failed"
15382 }
15383 run_test 128 "interactive lfs for 2 consecutive find's"
15384
15385 set_dir_limits () {
15386         local mntdev
15387         local canondev
15388         local node
15389
15390         local ldproc=/proc/fs/ldiskfs
15391         local facets=$(get_facets MDS)
15392
15393         for facet in ${facets//,/ }; do
15394                 canondev=$(ldiskfs_canon \
15395                            *.$(convert_facet2label $facet).mntdev $facet)
15396                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15397                         ldproc=/sys/fs/ldiskfs
15398                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15399                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15400         done
15401 }
15402
15403 check_mds_dmesg() {
15404         local facets=$(get_facets MDS)
15405         for facet in ${facets//,/ }; do
15406                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15407         done
15408         return 1
15409 }
15410
15411 test_129() {
15412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15413         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15414                 skip "Need MDS version with at least 2.5.56"
15415         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15416                 skip_env "ldiskfs only test"
15417         fi
15418         remote_mds_nodsh && skip "remote MDS with nodsh"
15419
15420         local ENOSPC=28
15421         local has_warning=false
15422
15423         rm -rf $DIR/$tdir
15424         mkdir -p $DIR/$tdir
15425
15426         # block size of mds1
15427         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15428         set_dir_limits $maxsize $((maxsize * 6 / 8))
15429         stack_trap "set_dir_limits 0 0"
15430         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15431         local dirsize=$(stat -c%s "$DIR/$tdir")
15432         local nfiles=0
15433         while (( $dirsize <= $maxsize )); do
15434                 $MCREATE $DIR/$tdir/file_base_$nfiles
15435                 rc=$?
15436                 # check two errors:
15437                 # ENOSPC for ext4 max_dir_size, which has been used since
15438                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15439                 if (( rc == ENOSPC )); then
15440                         set_dir_limits 0 0
15441                         echo "rc=$rc returned as expected after $nfiles files"
15442
15443                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15444                                 error "create failed w/o dir size limit"
15445
15446                         # messages may be rate limited if test is run repeatedly
15447                         check_mds_dmesg '"is approaching max"' ||
15448                                 echo "warning message should be output"
15449                         check_mds_dmesg '"has reached max"' ||
15450                                 echo "reached message should be output"
15451
15452                         dirsize=$(stat -c%s "$DIR/$tdir")
15453
15454                         [[ $dirsize -ge $maxsize ]] && return 0
15455                         error "dirsize $dirsize < $maxsize after $nfiles files"
15456                 elif (( rc != 0 )); then
15457                         break
15458                 fi
15459                 nfiles=$((nfiles + 1))
15460                 dirsize=$(stat -c%s "$DIR/$tdir")
15461         done
15462
15463         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15464 }
15465 run_test 129 "test directory size limit ========================"
15466
15467 OLDIFS="$IFS"
15468 cleanup_130() {
15469         trap 0
15470         IFS="$OLDIFS"
15471         rm -f $DIR/$tfile
15472 }
15473
15474 test_130a() {
15475         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15476         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15477
15478         trap cleanup_130 EXIT RETURN
15479
15480         local fm_file=$DIR/$tfile
15481         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15482         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15483                 error "dd failed for $fm_file"
15484
15485         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15486         filefrag -ves $fm_file
15487         local rc=$?
15488         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15489                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15490         (( $rc == 0 )) || error "filefrag $fm_file failed"
15491
15492         filefrag_op=$(filefrag -ve -k $fm_file |
15493                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15494         local lun=$($LFS getstripe -i $fm_file)
15495
15496         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15497         IFS=$'\n'
15498         local tot_len=0
15499         for line in $filefrag_op; do
15500                 local frag_lun=$(echo $line | cut -d: -f5)
15501                 local ext_len=$(echo $line | cut -d: -f4)
15502
15503                 if (( $frag_lun != $lun )); then
15504                         error "FIEMAP on 1-stripe file($fm_file) failed"
15505                         return
15506                 fi
15507                 (( tot_len += ext_len ))
15508         done
15509
15510         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15511                 error "FIEMAP on 1-stripe file($fm_file) failed"
15512                 return
15513         fi
15514
15515         echo "FIEMAP on single striped file succeeded"
15516 }
15517 run_test 130a "FIEMAP (1-stripe file)"
15518
15519 test_130b() {
15520         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15521
15522         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15523         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15524         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15525                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15526
15527         trap cleanup_130 EXIT RETURN
15528
15529         local fm_file=$DIR/$tfile
15530         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15531                 error "setstripe on $fm_file"
15532
15533         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15534                 error "dd failed on $fm_file"
15535
15536         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15537         filefrag_op=$(filefrag -ve -k $fm_file |
15538                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15539
15540         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15541                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15542
15543         IFS=$'\n'
15544         local tot_len=0
15545         local num_luns=1
15546
15547         for line in $filefrag_op; do
15548                 local frag_lun=$(echo $line | cut -d: -f5 |
15549                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15550                 local ext_len=$(echo $line | cut -d: -f4)
15551                 if (( $frag_lun != $last_lun )); then
15552                         if (( tot_len != 1024 )); then
15553                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15554                                 return
15555                         else
15556                                 (( num_luns += 1 ))
15557                                 tot_len=0
15558                         fi
15559                 fi
15560                 (( tot_len += ext_len ))
15561                 last_lun=$frag_lun
15562         done
15563         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15564                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15565                 return
15566         fi
15567
15568         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15569 }
15570 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15571
15572 test_130c() {
15573         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15574
15575         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15576         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15577         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15578                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15579
15580         trap cleanup_130 EXIT RETURN
15581
15582         local fm_file=$DIR/$tfile
15583         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15584
15585         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15586                 error "dd failed on $fm_file"
15587
15588         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15589         filefrag_op=$(filefrag -ve -k $fm_file |
15590                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15591
15592         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15593                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15594
15595         IFS=$'\n'
15596         local tot_len=0
15597         local num_luns=1
15598         for line in $filefrag_op; do
15599                 local frag_lun=$(echo $line | cut -d: -f5 |
15600                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15601                 local ext_len=$(echo $line | cut -d: -f4)
15602                 if (( $frag_lun != $last_lun )); then
15603                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15604                         if (( logical != 512 )); then
15605                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15606                                 return
15607                         fi
15608                         if (( tot_len != 512 )); then
15609                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15610                                 return
15611                         else
15612                                 (( num_luns += 1 ))
15613                                 tot_len=0
15614                         fi
15615                 fi
15616                 (( tot_len += ext_len ))
15617                 last_lun=$frag_lun
15618         done
15619         if (( num_luns != 2 || tot_len != 512 )); then
15620                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15621                 return
15622         fi
15623
15624         echo "FIEMAP on 2-stripe file with hole succeeded"
15625 }
15626 run_test 130c "FIEMAP (2-stripe file with hole)"
15627
15628 test_130d() {
15629         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15630
15631         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15632         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15633         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15634                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15635
15636         trap cleanup_130 EXIT RETURN
15637
15638         local fm_file=$DIR/$tfile
15639         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15640                         error "setstripe on $fm_file"
15641
15642         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15643         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15644                 error "dd failed on $fm_file"
15645
15646         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15647         filefrag_op=$(filefrag -ve -k $fm_file |
15648                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15649
15650         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15651                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15652
15653         IFS=$'\n'
15654         local tot_len=0
15655         local num_luns=1
15656         for line in $filefrag_op; do
15657                 local frag_lun=$(echo $line | cut -d: -f5 |
15658                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15659                 local ext_len=$(echo $line | cut -d: -f4)
15660                 if (( $frag_lun != $last_lun )); then
15661                         if (( tot_len != 1024 )); then
15662                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15663                                 return
15664                         else
15665                                 (( num_luns += 1 ))
15666                                 local tot_len=0
15667                         fi
15668                 fi
15669                 (( tot_len += ext_len ))
15670                 last_lun=$frag_lun
15671         done
15672         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15673                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15674                 return
15675         fi
15676
15677         echo "FIEMAP on N-stripe file succeeded"
15678 }
15679 run_test 130d "FIEMAP (N-stripe file)"
15680
15681 test_130e() {
15682         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15683
15684         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15685         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15686         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15687                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15688
15689         trap cleanup_130 EXIT RETURN
15690
15691         local fm_file=$DIR/$tfile
15692         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15693         stack_trap "rm -f $fm_file"
15694
15695         local num_blks=512
15696         local expected_len=$(( (num_blks / 2) * 64 ))
15697         for ((i = 0; i < $num_blks; i++)); do
15698                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15699                         conv=notrunc > /dev/null 2>&1
15700         done
15701
15702         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15703         filefrag_op=$(filefrag -ve -k $fm_file |
15704                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15705
15706         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15707
15708         IFS=$'\n'
15709         local tot_len=0
15710         local num_luns=1
15711         for line in $filefrag_op; do
15712                 local frag_lun=$(echo $line | cut -d: -f5)
15713                 local ext_len=$(echo $line | cut -d: -f4)
15714                 if (( $frag_lun != $last_lun )); then
15715                         if (( tot_len != $expected_len )); then
15716                                 error "OST$last_lun $tot_len != $expected_len"
15717                         else
15718                                 (( num_luns += 1 ))
15719                                 tot_len=0
15720                         fi
15721                 fi
15722                 (( tot_len += ext_len ))
15723                 last_lun=$frag_lun
15724         done
15725         if (( num_luns != 2 || tot_len != $expected_len )); then
15726                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15727         fi
15728
15729         echo "FIEMAP with continuation calls succeeded"
15730 }
15731 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15732
15733 test_130f() {
15734         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15735         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15736         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15737                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15738
15739         local fm_file=$DIR/$tfile
15740         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15741                 error "multiop create with lov_delay_create on $fm_file"
15742
15743         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15744         filefrag_extents=$(filefrag -vek $fm_file |
15745                            awk '/extents? found/ { print $2 }')
15746         if (( $filefrag_extents != 0 )); then
15747                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15748         fi
15749
15750         rm -f $fm_file
15751 }
15752 run_test 130f "FIEMAP (unstriped file)"
15753
15754 test_130g() {
15755         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15756                 skip "Need MDS version with at least 2.12.53 for overstriping"
15757         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15758         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15759         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15760                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15761
15762         local file=$DIR/$tfile
15763         local nr=$((OSTCOUNT * 100))
15764
15765         $LFS setstripe -C $nr -S1M $file ||
15766                 error "failed to setstripe -C $nr $file"
15767
15768         stack_trap "rm -f $file"
15769         dd if=/dev/zero of=$file count=$nr bs=1M
15770         sync
15771         nr=$($LFS getstripe -c $file)
15772
15773         local extents=$(filefrag -v $file |
15774                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15775
15776         echo "filefrag list $extents extents in file with stripecount $nr"
15777         if (( extents < nr )); then
15778                 $LFS getstripe $file
15779                 filefrag -v $file
15780                 error "filefrag printed $extents < $nr extents"
15781         fi
15782 }
15783 run_test 130g "FIEMAP (overstripe file)"
15784
15785 # Test for writev/readv
15786 test_131a() {
15787         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15788                 error "writev test failed"
15789         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15790                 error "readv failed"
15791         rm -f $DIR/$tfile
15792 }
15793 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15794
15795 test_131b() {
15796         local fsize=$((524288 + 1048576 + 1572864))
15797         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15798                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15799                         error "append writev test failed"
15800
15801         ((fsize += 1572864 + 1048576))
15802         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15803                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15804                         error "append writev test failed"
15805         rm -f $DIR/$tfile
15806 }
15807 run_test 131b "test append writev"
15808
15809 test_131c() {
15810         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15811         error "NOT PASS"
15812 }
15813 run_test 131c "test read/write on file w/o objects"
15814
15815 test_131d() {
15816         rwv -f $DIR/$tfile -w -n 1 1572864
15817         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15818         if [ "$NOB" != 1572864 ]; then
15819                 error "Short read filed: read $NOB bytes instead of 1572864"
15820         fi
15821         rm -f $DIR/$tfile
15822 }
15823 run_test 131d "test short read"
15824
15825 test_131e() {
15826         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15827         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15828         error "read hitting hole failed"
15829         rm -f $DIR/$tfile
15830 }
15831 run_test 131e "test read hitting hole"
15832
15833 check_stats() {
15834         local facet=$1
15835         local op=$2
15836         local want=${3:-0}
15837         local res
15838
15839         # open             11 samples [usecs] 468 4793 13658 35791898
15840         case $facet in
15841         mds*) res=($(do_facet $facet \
15842                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15843                  ;;
15844         ost*) res=($(do_facet $facet \
15845                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15846                  ;;
15847         *) error "Wrong facet '$facet'" ;;
15848         esac
15849         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15850         # if $want is zero, it means any stat increment is ok.
15851         if (( $want > 0 )); then
15852                 local count=${res[1]}
15853
15854                 if (( $count != $want )); then
15855                         if [[ $facet =~ "mds" ]]; then
15856                                 do_nodes $(comma_list $(mdts_nodes)) \
15857                                         $LCTL get_param mdt.*.md_stats
15858                         else
15859                                 do_nodes $(comma_list $(osts-nodes)) \
15860                                         $LCTL get_param obdfilter.*.stats
15861                         fi
15862                         error "The $op counter on $facet is $count, not $want"
15863                 fi
15864         fi
15865 }
15866
15867 test_133a() {
15868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15869         remote_ost_nodsh && skip "remote OST with nodsh"
15870         remote_mds_nodsh && skip "remote MDS with nodsh"
15871         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15872                 skip_env "MDS doesn't support rename stats"
15873
15874         local testdir=$DIR/${tdir}/stats_testdir
15875
15876         mkdir_on_mdt0 $DIR/${tdir}
15877
15878         # clear stats.
15879         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15880         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15881
15882         # verify mdt stats first.
15883         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15884         check_stats $SINGLEMDS "mkdir" 1
15885
15886         # clear "open" from "lfs mkdir" above
15887         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15888         touch ${testdir}/${tfile} || error "touch failed"
15889         check_stats $SINGLEMDS "open" 1
15890         check_stats $SINGLEMDS "close" 1
15891         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
15892                 # open should match close
15893                 ls -lR ${testdir}
15894                 check_stats $SINGLEMDS "open" 2
15895                 check_stats $SINGLEMDS "close" 2
15896         }
15897         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15898                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15899                 check_stats $SINGLEMDS "mknod" 2
15900         }
15901         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15902         check_stats $SINGLEMDS "unlink" 1
15903         rm -f ${testdir}/${tfile} || error "file remove failed"
15904         check_stats $SINGLEMDS "unlink" 2
15905
15906         # remove working dir and check mdt stats again.
15907         rmdir ${testdir} || error "rmdir failed"
15908         check_stats $SINGLEMDS "rmdir" 1
15909
15910         local testdir1=$DIR/${tdir}/stats_testdir1
15911         mkdir_on_mdt0 ${testdir}
15912         mkdir_on_mdt0 ${testdir1}
15913         touch ${testdir1}/test1
15914         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15915         check_stats $SINGLEMDS "crossdir_rename" 1
15916
15917         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15918         check_stats $SINGLEMDS "samedir_rename" 1
15919
15920         rm -rf $DIR/${tdir}
15921 }
15922 run_test 133a "Verifying MDT stats ========================================"
15923
15924 test_133b() {
15925         local res
15926
15927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15928         remote_ost_nodsh && skip "remote OST with nodsh"
15929         remote_mds_nodsh && skip "remote MDS with nodsh"
15930
15931         local testdir=$DIR/${tdir}/stats_testdir
15932
15933         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15934         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15935         touch ${testdir}/${tfile} || error "touch failed"
15936         cancel_lru_locks mdc
15937
15938         # clear stats.
15939         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15940         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15941
15942         # extra mdt stats verification.
15943         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15944         check_stats $SINGLEMDS "setattr" 1
15945         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15946         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15947         then            # LU-1740
15948                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15949                 check_stats $SINGLEMDS "getattr" 1
15950         fi
15951         rm -rf $DIR/${tdir}
15952
15953         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15954         # so the check below is not reliable
15955         [ $MDSCOUNT -eq 1 ] || return 0
15956
15957         # Sleep to avoid a cached response.
15958         #define OBD_STATFS_CACHE_SECONDS 1
15959         sleep 2
15960         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15961         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15962         $LFS df || error "lfs failed"
15963         check_stats $SINGLEMDS "statfs" 1
15964
15965         # check aggregated statfs (LU-10018)
15966         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15967                 return 0
15968         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15969                 return 0
15970         sleep 2
15971         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15972         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15973         df $DIR
15974         check_stats $SINGLEMDS "statfs" 1
15975
15976         # We want to check that the client didn't send OST_STATFS to
15977         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15978         # extra care is needed here.
15979         if remote_mds; then
15980                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15981                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15982
15983                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15984                 [ "$res" ] && error "OST got STATFS"
15985         fi
15986
15987         return 0
15988 }
15989 run_test 133b "Verifying extra MDT stats =================================="
15990
15991 test_133c() {
15992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15993         remote_ost_nodsh && skip "remote OST with nodsh"
15994         remote_mds_nodsh && skip "remote MDS with nodsh"
15995
15996         local testdir=$DIR/$tdir/stats_testdir
15997
15998         test_mkdir -p $testdir
15999
16000         # verify obdfilter stats.
16001         $LFS setstripe -c 1 -i 0 $testdir/$tfile
16002         sync
16003         cancel_lru_locks osc
16004         wait_delete_completed
16005
16006         # clear stats.
16007         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
16008         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
16009
16010         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
16011                 error "dd failed"
16012         sync
16013         cancel_lru_locks osc
16014         check_stats ost1 "write" 1
16015
16016         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
16017         check_stats ost1 "read" 1
16018
16019         > $testdir/$tfile || error "truncate failed"
16020         check_stats ost1 "punch" 1
16021
16022         rm -f $testdir/$tfile || error "file remove failed"
16023         wait_delete_completed
16024         check_stats ost1 "destroy" 1
16025
16026         rm -rf $DIR/$tdir
16027 }
16028 run_test 133c "Verifying OST stats ========================================"
16029
16030 order_2() {
16031         local value=$1
16032         local orig=$value
16033         local order=1
16034
16035         while [ $value -ge 2 ]; do
16036                 order=$((order*2))
16037                 value=$((value/2))
16038         done
16039
16040         if [ $orig -gt $order ]; then
16041                 order=$((order*2))
16042         fi
16043         echo $order
16044 }
16045
16046 size_in_KMGT() {
16047     local value=$1
16048     local size=('K' 'M' 'G' 'T');
16049     local i=0
16050     local size_string=$value
16051
16052     while [ $value -ge 1024 ]; do
16053         if [ $i -gt 3 ]; then
16054             #T is the biggest unit we get here, if that is bigger,
16055             #just return XXXT
16056             size_string=${value}T
16057             break
16058         fi
16059         value=$((value >> 10))
16060         if [ $value -lt 1024 ]; then
16061             size_string=${value}${size[$i]}
16062             break
16063         fi
16064         i=$((i + 1))
16065     done
16066
16067     echo $size_string
16068 }
16069
16070 get_rename_size() {
16071         local size=$1
16072         local context=${2:-.}
16073         local sample=$(do_facet $SINGLEMDS $LCTL \
16074                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16075                 grep -A1 $context |
16076                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16077         echo $sample
16078 }
16079
16080 test_133d() {
16081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16082         remote_ost_nodsh && skip "remote OST with nodsh"
16083         remote_mds_nodsh && skip "remote MDS with nodsh"
16084         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16085                 skip_env "MDS doesn't support rename stats"
16086
16087         local testdir1=$DIR/${tdir}/stats_testdir1
16088         local testdir2=$DIR/${tdir}/stats_testdir2
16089         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16090
16091         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16092
16093         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16094         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16095
16096         createmany -o $testdir1/test 512 || error "createmany failed"
16097
16098         # check samedir rename size
16099         mv ${testdir1}/test0 ${testdir1}/test_0
16100
16101         local testdir1_size=$(ls -l $DIR/${tdir} |
16102                 awk '/stats_testdir1/ {print $5}')
16103         local testdir2_size=$(ls -l $DIR/${tdir} |
16104                 awk '/stats_testdir2/ {print $5}')
16105
16106         testdir1_size=$(order_2 $testdir1_size)
16107         testdir2_size=$(order_2 $testdir2_size)
16108
16109         testdir1_size=$(size_in_KMGT $testdir1_size)
16110         testdir2_size=$(size_in_KMGT $testdir2_size)
16111
16112         echo "source rename dir size: ${testdir1_size}"
16113         echo "target rename dir size: ${testdir2_size}"
16114
16115         local cmd="do_facet $SINGLEMDS $LCTL "
16116         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16117
16118         eval $cmd || error "$cmd failed"
16119         local samedir=$($cmd | grep 'same_dir')
16120         local same_sample=$(get_rename_size $testdir1_size)
16121         [ -z "$samedir" ] && error "samedir_rename_size count error"
16122         [[ $same_sample -eq 1 ]] ||
16123                 error "samedir_rename_size error $same_sample"
16124         echo "Check same dir rename stats success"
16125
16126         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16127
16128         # check crossdir rename size
16129         mv ${testdir1}/test_0 ${testdir2}/test_0
16130
16131         testdir1_size=$(ls -l $DIR/${tdir} |
16132                 awk '/stats_testdir1/ {print $5}')
16133         testdir2_size=$(ls -l $DIR/${tdir} |
16134                 awk '/stats_testdir2/ {print $5}')
16135
16136         testdir1_size=$(order_2 $testdir1_size)
16137         testdir2_size=$(order_2 $testdir2_size)
16138
16139         testdir1_size=$(size_in_KMGT $testdir1_size)
16140         testdir2_size=$(size_in_KMGT $testdir2_size)
16141
16142         echo "source rename dir size: ${testdir1_size}"
16143         echo "target rename dir size: ${testdir2_size}"
16144
16145         eval $cmd || error "$cmd failed"
16146         local crossdir=$($cmd | grep 'crossdir')
16147         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16148         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16149         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16150         [[ $src_sample -eq 1 ]] ||
16151                 error "crossdir_rename_size error $src_sample"
16152         [[ $tgt_sample -eq 1 ]] ||
16153                 error "crossdir_rename_size error $tgt_sample"
16154         echo "Check cross dir rename stats success"
16155         rm -rf $DIR/${tdir}
16156 }
16157 run_test 133d "Verifying rename_stats ========================================"
16158
16159 test_133e() {
16160         remote_mds_nodsh && skip "remote MDS with nodsh"
16161         remote_ost_nodsh && skip "remote OST with nodsh"
16162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16163
16164         local testdir=$DIR/${tdir}/stats_testdir
16165         local ctr f0 f1 bs=32768 count=42 sum
16166
16167         mkdir -p ${testdir} || error "mkdir failed"
16168
16169         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16170
16171         for ctr in {write,read}_bytes; do
16172                 sync
16173                 cancel_lru_locks osc
16174
16175                 do_facet ost1 $LCTL set_param -n \
16176                         "obdfilter.*.exports.clear=clear"
16177
16178                 if [ $ctr = write_bytes ]; then
16179                         f0=/dev/zero
16180                         f1=${testdir}/${tfile}
16181                 else
16182                         f0=${testdir}/${tfile}
16183                         f1=/dev/null
16184                 fi
16185
16186                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16187                         error "dd failed"
16188                 sync
16189                 cancel_lru_locks osc
16190
16191                 sum=$(do_facet ost1 $LCTL get_param \
16192                         "obdfilter.*.exports.*.stats" |
16193                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16194                                 $1 == ctr { sum += $7 }
16195                                 END { printf("%0.0f", sum) }')
16196
16197                 if ((sum != bs * count)); then
16198                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16199                 fi
16200         done
16201
16202         rm -rf $DIR/${tdir}
16203 }
16204 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16205
16206 test_133f() {
16207         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16208                 skip "too old lustre for get_param -R ($facet_ver)"
16209
16210         # verifying readability.
16211         $LCTL get_param -R '*' &> /dev/null
16212
16213         # Verifing writability with badarea_io.
16214         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16215         local skipped_params='force_lbug|changelog_mask|daemon_file'
16216         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16217                 egrep -v "$skipped_params" |
16218                 xargs -n 1 find $proc_dirs -name |
16219                 xargs -n 1 badarea_io ||
16220                 error "client badarea_io failed"
16221
16222         # remount the FS in case writes/reads /proc break the FS
16223         cleanup || error "failed to unmount"
16224         setup || error "failed to setup"
16225 }
16226 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16227
16228 test_133g() {
16229         remote_mds_nodsh && skip "remote MDS with nodsh"
16230         remote_ost_nodsh && skip "remote OST with nodsh"
16231
16232         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16233         local proc_dirs_str=$(eval echo $proc_dirs)
16234         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16235         local facet
16236         for facet in mds1 ost1; do
16237                 local facet_ver=$(lustre_version_code $facet)
16238                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16239                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16240                 else
16241                         log "$facet: too old lustre for get_param -R"
16242                 fi
16243                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16244                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16245                                 tr -d = | egrep -v $skipped_params |
16246                                 xargs -n 1 find $proc_dirs_str -name |
16247                                 xargs -n 1 badarea_io" ||
16248                                         error "$facet badarea_io failed"
16249                 else
16250                         skip_noexit "$facet: too old lustre for get_param -R"
16251                 fi
16252         done
16253
16254         # remount the FS in case writes/reads /proc break the FS
16255         cleanup || error "failed to unmount"
16256         setup || error "failed to setup"
16257 }
16258 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16259
16260 test_133h() {
16261         remote_mds_nodsh && skip "remote MDS with nodsh"
16262         remote_ost_nodsh && skip "remote OST with nodsh"
16263         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16264                 skip "Need MDS version at least 2.9.54"
16265
16266         local facet
16267         for facet in client mds1 ost1; do
16268                 # Get the list of files that are missing the terminating newline
16269                 local plist=$(do_facet $facet
16270                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16271                 local ent
16272                 for ent in $plist; do
16273                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16274                                 awk -v FS='\v' -v RS='\v\v' \
16275                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16276                                         print FILENAME}'" 2>/dev/null)
16277                         [ -z $missing ] || {
16278                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16279                                 error "file does not end with newline: $facet-$ent"
16280                         }
16281                 done
16282         done
16283 }
16284 run_test 133h "Proc files should end with newlines"
16285
16286 test_134a() {
16287         remote_mds_nodsh && skip "remote MDS with nodsh"
16288         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16289                 skip "Need MDS version at least 2.7.54"
16290
16291         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16292         cancel_lru_locks mdc
16293
16294         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16295         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16296         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16297
16298         local nr=1000
16299         createmany -o $DIR/$tdir/f $nr ||
16300                 error "failed to create $nr files in $DIR/$tdir"
16301         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16302
16303         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16304         do_facet mds1 $LCTL set_param fail_loc=0x327
16305         do_facet mds1 $LCTL set_param fail_val=500
16306         touch $DIR/$tdir/m
16307
16308         echo "sleep 10 seconds ..."
16309         sleep 10
16310         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16311
16312         do_facet mds1 $LCTL set_param fail_loc=0
16313         do_facet mds1 $LCTL set_param fail_val=0
16314         [ $lck_cnt -lt $unused ] ||
16315                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16316
16317         rm $DIR/$tdir/m
16318         unlinkmany $DIR/$tdir/f $nr
16319 }
16320 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16321
16322 test_134b() {
16323         remote_mds_nodsh && skip "remote MDS with nodsh"
16324         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16325                 skip "Need MDS version at least 2.7.54"
16326
16327         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16328         cancel_lru_locks mdc
16329
16330         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16331                         ldlm.lock_reclaim_threshold_mb)
16332         # disable reclaim temporarily
16333         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16334
16335         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16336         do_facet mds1 $LCTL set_param fail_loc=0x328
16337         do_facet mds1 $LCTL set_param fail_val=500
16338
16339         $LCTL set_param debug=+trace
16340
16341         local nr=600
16342         createmany -o $DIR/$tdir/f $nr &
16343         local create_pid=$!
16344
16345         echo "Sleep $TIMEOUT seconds ..."
16346         sleep $TIMEOUT
16347         if ! ps -p $create_pid  > /dev/null 2>&1; then
16348                 do_facet mds1 $LCTL set_param fail_loc=0
16349                 do_facet mds1 $LCTL set_param fail_val=0
16350                 do_facet mds1 $LCTL set_param \
16351                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16352                 error "createmany finished incorrectly!"
16353         fi
16354         do_facet mds1 $LCTL set_param fail_loc=0
16355         do_facet mds1 $LCTL set_param fail_val=0
16356         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16357         wait $create_pid || return 1
16358
16359         unlinkmany $DIR/$tdir/f $nr
16360 }
16361 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16362
16363 test_135() {
16364         remote_mds_nodsh && skip "remote MDS with nodsh"
16365         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16366                 skip "Need MDS version at least 2.13.50"
16367         local fname
16368
16369         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16370
16371 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16372         #set only one record at plain llog
16373         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16374
16375         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16376
16377         #fill already existed plain llog each 64767
16378         #wrapping whole catalog
16379         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16380
16381         createmany -o $DIR/$tdir/$tfile_ 64700
16382         for (( i = 0; i < 64700; i = i + 2 ))
16383         do
16384                 rm $DIR/$tdir/$tfile_$i &
16385                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16386                 local pid=$!
16387                 wait $pid
16388         done
16389
16390         #waiting osp synchronization
16391         wait_delete_completed
16392 }
16393 run_test 135 "Race catalog processing"
16394
16395 test_136() {
16396         remote_mds_nodsh && skip "remote MDS with nodsh"
16397         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16398                 skip "Need MDS version at least 2.13.50"
16399         local fname
16400
16401         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16402         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16403         #set only one record at plain llog
16404 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16405         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16406
16407         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16408
16409         #fill already existed 2 plain llogs each 64767
16410         #wrapping whole catalog
16411         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16412         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16413         wait_delete_completed
16414
16415         createmany -o $DIR/$tdir/$tfile_ 10
16416         sleep 25
16417
16418         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16419         for (( i = 0; i < 10; i = i + 3 ))
16420         do
16421                 rm $DIR/$tdir/$tfile_$i &
16422                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16423                 local pid=$!
16424                 wait $pid
16425                 sleep 7
16426                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16427         done
16428
16429         #waiting osp synchronization
16430         wait_delete_completed
16431 }
16432 run_test 136 "Race catalog processing 2"
16433
16434 test_140() { #bug-17379
16435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16436
16437         test_mkdir $DIR/$tdir
16438         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16439         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16440
16441         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16442         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16443         local i=0
16444         while i=$((i + 1)); do
16445                 test_mkdir $i
16446                 cd $i || error "Changing to $i"
16447                 ln -s ../stat stat || error "Creating stat symlink"
16448                 # Read the symlink until ELOOP present,
16449                 # not LBUGing the system is considered success,
16450                 # we didn't overrun the stack.
16451                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16452                 if [ $ret -ne 0 ]; then
16453                         if [ $ret -eq 40 ]; then
16454                                 break  # -ELOOP
16455                         else
16456                                 error "Open stat symlink"
16457                                         return
16458                         fi
16459                 fi
16460         done
16461         i=$((i - 1))
16462         echo "The symlink depth = $i"
16463         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16464                 error "Invalid symlink depth"
16465
16466         # Test recursive symlink
16467         ln -s symlink_self symlink_self
16468         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16469         echo "open symlink_self returns $ret"
16470         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16471 }
16472 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16473
16474 test_150a() {
16475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16476
16477         local TF="$TMP/$tfile"
16478
16479         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16480         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16481         cp $TF $DIR/$tfile
16482         cancel_lru_locks $OSC
16483         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16484         remount_client $MOUNT
16485         df -P $MOUNT
16486         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16487
16488         $TRUNCATE $TF 6000
16489         $TRUNCATE $DIR/$tfile 6000
16490         cancel_lru_locks $OSC
16491         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16492
16493         echo "12345" >>$TF
16494         echo "12345" >>$DIR/$tfile
16495         cancel_lru_locks $OSC
16496         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16497
16498         echo "12345" >>$TF
16499         echo "12345" >>$DIR/$tfile
16500         cancel_lru_locks $OSC
16501         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16502 }
16503 run_test 150a "truncate/append tests"
16504
16505 test_150b() {
16506         check_set_fallocate_or_skip
16507         local out
16508
16509         touch $DIR/$tfile
16510         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16511         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16512                 skip_eopnotsupp "$out|check_fallocate failed"
16513 }
16514 run_test 150b "Verify fallocate (prealloc) functionality"
16515
16516 test_150bb() {
16517         check_set_fallocate_or_skip
16518
16519         touch $DIR/$tfile
16520         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16521         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16522         > $DIR/$tfile
16523         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16524         # precomputed md5sum for 20MB of zeroes
16525         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16526         local sum=($(md5sum $DIR/$tfile))
16527
16528         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16529
16530         check_set_fallocate 1
16531
16532         > $DIR/$tfile
16533         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16534         sum=($(md5sum $DIR/$tfile))
16535
16536         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16537 }
16538 run_test 150bb "Verify fallocate modes both zero space"
16539
16540 test_150c() {
16541         check_set_fallocate_or_skip
16542         local striping="-c2"
16543
16544         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16545         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16546         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16547         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16548         local want=$((OSTCOUNT * 1048576))
16549
16550         # Must allocate all requested space, not more than 5% extra
16551         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16552                 error "bytes $bytes is not $want"
16553
16554         rm -f $DIR/$tfile
16555
16556         echo "verify fallocate on PFL file"
16557
16558         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16559
16560         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16561                 error "Create $DIR/$tfile failed"
16562         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16563         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16564         want=$((512 * 1048576))
16565
16566         # Must allocate all requested space, not more than 5% extra
16567         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16568                 error "bytes $bytes is not $want"
16569 }
16570 run_test 150c "Verify fallocate Size and Blocks"
16571
16572 test_150d() {
16573         check_set_fallocate_or_skip
16574         local striping="-c2"
16575
16576         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16577
16578         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16579         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16580                 error "setstripe failed"
16581         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16582         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16583         local want=$((OSTCOUNT * 1048576))
16584
16585         # Must allocate all requested space, not more than 5% extra
16586         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16587                 error "bytes $bytes is not $want"
16588 }
16589 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16590
16591 test_150e() {
16592         check_set_fallocate_or_skip
16593
16594         echo "df before:"
16595         $LFS df
16596         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16597         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16598                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16599
16600         # Find OST with Minimum Size
16601         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16602                        sort -un | head -1)
16603
16604         # Get 100MB per OST of the available space to reduce run time
16605         # else 60% of the available space if we are running SLOW tests
16606         if [ $SLOW == "no" ]; then
16607                 local space=$((1024 * 100 * OSTCOUNT))
16608         else
16609                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16610         fi
16611
16612         fallocate -l${space}k $DIR/$tfile ||
16613                 error "fallocate ${space}k $DIR/$tfile failed"
16614         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16615
16616         # get size immediately after fallocate. This should be correctly
16617         # updated
16618         local size=$(stat -c '%s' $DIR/$tfile)
16619         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16620
16621         # Sleep for a while for statfs to get updated. And not pull from cache.
16622         sleep 2
16623
16624         echo "df after fallocate:"
16625         $LFS df
16626
16627         (( size / 1024 == space )) || error "size $size != requested $space"
16628         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16629                 error "used $used < space $space"
16630
16631         rm $DIR/$tfile || error "rm failed"
16632         sync
16633         wait_delete_completed
16634
16635         echo "df after unlink:"
16636         $LFS df
16637 }
16638 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16639
16640 test_150f() {
16641         local size
16642         local blocks
16643         local want_size_before=20480 # in bytes
16644         local want_blocks_before=40 # 512 sized blocks
16645         local want_blocks_after=24  # 512 sized blocks
16646         local length=$(((want_blocks_before - want_blocks_after) * 512))
16647
16648         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16649                 skip "need at least 2.14.0 for fallocate punch"
16650
16651         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16652                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16653         fi
16654
16655         check_set_fallocate_or_skip
16656         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16657
16658         [[ "x$DOM" == "xyes" ]] &&
16659                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16660
16661         echo "Verify fallocate punch: Range within the file range"
16662         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16663                 error "dd failed for bs 4096 and count 5"
16664
16665         # Call fallocate with punch range which is within the file range
16666         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16667                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16668         # client must see changes immediately after fallocate
16669         size=$(stat -c '%s' $DIR/$tfile)
16670         blocks=$(stat -c '%b' $DIR/$tfile)
16671
16672         # Verify punch worked.
16673         (( blocks == want_blocks_after )) ||
16674                 error "punch failed: blocks $blocks != $want_blocks_after"
16675
16676         (( size == want_size_before )) ||
16677                 error "punch failed: size $size != $want_size_before"
16678
16679         # Verify there is hole in file
16680         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16681         # precomputed md5sum
16682         local expect="4a9a834a2db02452929c0a348273b4aa"
16683
16684         cksum=($(md5sum $DIR/$tfile))
16685         [[ "${cksum[0]}" == "$expect" ]] ||
16686                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16687
16688         # Start second sub-case for fallocate punch.
16689         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16690         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16691                 error "dd failed for bs 4096 and count 5"
16692
16693         # Punch range less than block size will have no change in block count
16694         want_blocks_after=40  # 512 sized blocks
16695
16696         # Punch overlaps two blocks and less than blocksize
16697         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16698                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16699         size=$(stat -c '%s' $DIR/$tfile)
16700         blocks=$(stat -c '%b' $DIR/$tfile)
16701
16702         # Verify punch worked.
16703         (( blocks == want_blocks_after )) ||
16704                 error "punch failed: blocks $blocks != $want_blocks_after"
16705
16706         (( size == want_size_before )) ||
16707                 error "punch failed: size $size != $want_size_before"
16708
16709         # Verify if range is really zero'ed out. We expect Zeros.
16710         # precomputed md5sum
16711         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16712         cksum=($(md5sum $DIR/$tfile))
16713         [[ "${cksum[0]}" == "$expect" ]] ||
16714                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16715 }
16716 run_test 150f "Verify fallocate punch functionality"
16717
16718 test_150g() {
16719         local space
16720         local size
16721         local blocks
16722         local blocks_after
16723         local size_after
16724         local BS=4096 # Block size in bytes
16725
16726         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16727                 skip "need at least 2.14.0 for fallocate punch"
16728
16729         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16730                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16731         fi
16732
16733         check_set_fallocate_or_skip
16734         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16735
16736         if [[ "x$DOM" == "xyes" ]]; then
16737                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16738                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16739         else
16740                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16741                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16742         fi
16743
16744         # Get 100MB per OST of the available space to reduce run time
16745         # else 60% of the available space if we are running SLOW tests
16746         if [ $SLOW == "no" ]; then
16747                 space=$((1024 * 100 * OSTCOUNT))
16748         else
16749                 # Find OST with Minimum Size
16750                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16751                         sort -un | head -1)
16752                 echo "min size OST: $space"
16753                 space=$(((space * 60)/100 * OSTCOUNT))
16754         fi
16755         # space in 1k units, round to 4k blocks
16756         local blkcount=$((space * 1024 / $BS))
16757
16758         echo "Verify fallocate punch: Very large Range"
16759         fallocate -l${space}k $DIR/$tfile ||
16760                 error "fallocate ${space}k $DIR/$tfile failed"
16761         # write 1M at the end, start and in the middle
16762         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16763                 error "dd failed: bs $BS count 256"
16764         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16765                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16766         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16767                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16768
16769         # Gather stats.
16770         size=$(stat -c '%s' $DIR/$tfile)
16771
16772         # gather punch length.
16773         local punch_size=$((size - (BS * 2)))
16774
16775         echo "punch_size = $punch_size"
16776         echo "size - punch_size: $((size - punch_size))"
16777         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16778
16779         # Call fallocate to punch all except 2 blocks. We leave the
16780         # first and the last block
16781         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16782         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16783                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16784
16785         size_after=$(stat -c '%s' $DIR/$tfile)
16786         blocks_after=$(stat -c '%b' $DIR/$tfile)
16787
16788         # Verify punch worked.
16789         # Size should be kept
16790         (( size == size_after )) ||
16791                 error "punch failed: size $size != $size_after"
16792
16793         # two 4k data blocks to remain plus possible 1 extra extent block
16794         (( blocks_after <= ((BS / 512) * 3) )) ||
16795                 error "too many blocks remains: $blocks_after"
16796
16797         # Verify that file has hole between the first and the last blocks
16798         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16799         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16800
16801         echo "Hole at [$hole_start, $hole_end)"
16802         (( hole_start == BS )) ||
16803                 error "no hole at offset $BS after punch"
16804
16805         (( hole_end == BS + punch_size )) ||
16806                 error "data at offset $hole_end < $((BS + punch_size))"
16807 }
16808 run_test 150g "Verify fallocate punch on large range"
16809
16810 test_150h() {
16811         local file=$DIR/$tfile
16812         local size
16813
16814         check_set_fallocate_or_skip
16815         statx_supported || skip_env "Test must be statx() syscall supported"
16816
16817         # fallocate() does not update the size information on the MDT
16818         fallocate -l 16K $file || error "failed to fallocate $file"
16819         cancel_lru_locks $OSC
16820         # STATX with cached-always mode will not send glimpse RPCs to OST,
16821         # it uses the caching attrs on the client side as much as possible.
16822         size=$($STATX --cached=always -c %s $file)
16823         [ $size == 16384 ] ||
16824                 error "size after fallocate() is $size, expected 16384"
16825 }
16826 run_test 150h "Verify extend fallocate updates the file size"
16827
16828 #LU-2902 roc_hit was not able to read all values from lproc
16829 function roc_hit_init() {
16830         local list=$(comma_list $(osts_nodes))
16831         local dir=$DIR/$tdir-check
16832         local file=$dir/$tfile
16833         local BEFORE
16834         local AFTER
16835         local idx
16836
16837         test_mkdir $dir
16838         #use setstripe to do a write to every ost
16839         for i in $(seq 0 $((OSTCOUNT-1))); do
16840                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16841                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16842                 idx=$(printf %04x $i)
16843                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16844                         awk '$1 == "cache_access" {sum += $7}
16845                                 END { printf("%0.0f", sum) }')
16846
16847                 cancel_lru_locks osc
16848                 cat $file >/dev/null
16849
16850                 AFTER=$(get_osd_param $list *OST*$idx stats |
16851                         awk '$1 == "cache_access" {sum += $7}
16852                                 END { printf("%0.0f", sum) }')
16853
16854                 echo BEFORE:$BEFORE AFTER:$AFTER
16855                 if ! let "AFTER - BEFORE == 4"; then
16856                         rm -rf $dir
16857                         error "roc_hit is not safe to use"
16858                 fi
16859                 rm $file
16860         done
16861
16862         rm -rf $dir
16863 }
16864
16865 function roc_hit() {
16866         local list=$(comma_list $(osts_nodes))
16867         echo $(get_osd_param $list '' stats |
16868                 awk '$1 == "cache_hit" {sum += $7}
16869                         END { printf("%0.0f", sum) }')
16870 }
16871
16872 function set_cache() {
16873         local on=1
16874
16875         if [ "$2" == "off" ]; then
16876                 on=0;
16877         fi
16878         local list=$(comma_list $(osts_nodes))
16879         set_osd_param $list '' $1_cache_enable $on
16880
16881         cancel_lru_locks osc
16882 }
16883
16884 test_151() {
16885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16886         remote_ost_nodsh && skip "remote OST with nodsh"
16887         (( CLIENT_VERSION == OST1_VERSION )) ||
16888                 skip "LU-13081: no interop testing for OSS cache"
16889
16890         local CPAGES=3
16891         local list=$(comma_list $(osts_nodes))
16892
16893         # check whether obdfilter is cache capable at all
16894         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16895                 skip "not cache-capable obdfilter"
16896         fi
16897
16898         # check cache is enabled on all obdfilters
16899         if get_osd_param $list '' read_cache_enable | grep 0; then
16900                 skip "oss cache is disabled"
16901         fi
16902
16903         set_osd_param $list '' writethrough_cache_enable 1
16904
16905         # check write cache is enabled on all obdfilters
16906         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16907                 skip "oss write cache is NOT enabled"
16908         fi
16909
16910         roc_hit_init
16911
16912         #define OBD_FAIL_OBD_NO_LRU  0x609
16913         do_nodes $list $LCTL set_param fail_loc=0x609
16914
16915         # pages should be in the case right after write
16916         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16917                 error "dd failed"
16918
16919         local BEFORE=$(roc_hit)
16920         cancel_lru_locks osc
16921         cat $DIR/$tfile >/dev/null
16922         local AFTER=$(roc_hit)
16923
16924         do_nodes $list $LCTL set_param fail_loc=0
16925
16926         if ! let "AFTER - BEFORE == CPAGES"; then
16927                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16928         fi
16929
16930         cancel_lru_locks osc
16931         # invalidates OST cache
16932         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16933         set_osd_param $list '' read_cache_enable 0
16934         cat $DIR/$tfile >/dev/null
16935
16936         # now data shouldn't be found in the cache
16937         BEFORE=$(roc_hit)
16938         cancel_lru_locks osc
16939         cat $DIR/$tfile >/dev/null
16940         AFTER=$(roc_hit)
16941         if let "AFTER - BEFORE != 0"; then
16942                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16943         fi
16944
16945         set_osd_param $list '' read_cache_enable 1
16946         rm -f $DIR/$tfile
16947 }
16948 run_test 151 "test cache on oss and controls ==============================="
16949
16950 test_152() {
16951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16952
16953         local TF="$TMP/$tfile"
16954
16955         # simulate ENOMEM during write
16956 #define OBD_FAIL_OST_NOMEM      0x226
16957         lctl set_param fail_loc=0x80000226
16958         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16959         cp $TF $DIR/$tfile
16960         sync || error "sync failed"
16961         lctl set_param fail_loc=0
16962
16963         # discard client's cache
16964         cancel_lru_locks osc
16965
16966         # simulate ENOMEM during read
16967         lctl set_param fail_loc=0x80000226
16968         cmp $TF $DIR/$tfile || error "cmp failed"
16969         lctl set_param fail_loc=0
16970
16971         rm -f $TF
16972 }
16973 run_test 152 "test read/write with enomem ============================"
16974
16975 test_153() {
16976         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16977 }
16978 run_test 153 "test if fdatasync does not crash ======================="
16979
16980 dot_lustre_fid_permission_check() {
16981         local fid=$1
16982         local ffid=$MOUNT/.lustre/fid/$fid
16983         local test_dir=$2
16984
16985         echo "stat fid $fid"
16986         stat $ffid || error "stat $ffid failed."
16987         echo "touch fid $fid"
16988         touch $ffid || error "touch $ffid failed."
16989         echo "write to fid $fid"
16990         cat /etc/hosts > $ffid || error "write $ffid failed."
16991         echo "read fid $fid"
16992         diff /etc/hosts $ffid || error "read $ffid failed."
16993         echo "append write to fid $fid"
16994         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16995         echo "rename fid $fid"
16996         mv $ffid $test_dir/$tfile.1 &&
16997                 error "rename $ffid to $tfile.1 should fail."
16998         touch $test_dir/$tfile.1
16999         mv $test_dir/$tfile.1 $ffid &&
17000                 error "rename $tfile.1 to $ffid should fail."
17001         rm -f $test_dir/$tfile.1
17002         echo "truncate fid $fid"
17003         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
17004         echo "link fid $fid"
17005         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
17006         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
17007                 id $USER0 || skip_env "missing user $USER0"
17008                 echo "setfacl fid $fid"
17009                 setfacl -R -m u:$USER0:rwx $ffid ||
17010                         error "setfacl $ffid failed"
17011                 echo "getfacl fid $fid"
17012                 getfacl $ffid || error "getfacl $ffid failed."
17013         fi
17014         echo "unlink fid $fid"
17015         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
17016         echo "mknod fid $fid"
17017         mknod $ffid c 1 3 && error "mknod $ffid should fail."
17018
17019         fid=[0xf00000400:0x1:0x0]
17020         ffid=$MOUNT/.lustre/fid/$fid
17021
17022         echo "stat non-exist fid $fid"
17023         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
17024         echo "write to non-exist fid $fid"
17025         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
17026         echo "link new fid $fid"
17027         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
17028
17029         mkdir -p $test_dir/$tdir
17030         touch $test_dir/$tdir/$tfile
17031         fid=$($LFS path2fid $test_dir/$tdir)
17032         rc=$?
17033         [ $rc -ne 0 ] &&
17034                 error "error: could not get fid for $test_dir/$dir/$tfile."
17035
17036         ffid=$MOUNT/.lustre/fid/$fid
17037
17038         echo "ls $fid"
17039         ls $ffid || error "ls $ffid failed."
17040         echo "touch $fid/$tfile.1"
17041         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17042
17043         echo "touch $MOUNT/.lustre/fid/$tfile"
17044         touch $MOUNT/.lustre/fid/$tfile && \
17045                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17046
17047         echo "setxattr to $MOUNT/.lustre/fid"
17048         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17049
17050         echo "listxattr for $MOUNT/.lustre/fid"
17051         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17052
17053         echo "delxattr from $MOUNT/.lustre/fid"
17054         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17055
17056         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17057         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17058                 error "touch invalid fid should fail."
17059
17060         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17061         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17062                 error "touch non-normal fid should fail."
17063
17064         echo "rename $tdir to $MOUNT/.lustre/fid"
17065         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17066                 error "rename to $MOUNT/.lustre/fid should fail."
17067
17068         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17069         then            # LU-3547
17070                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17071                 local new_obf_mode=777
17072
17073                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17074                 chmod $new_obf_mode $DIR/.lustre/fid ||
17075                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17076
17077                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17078                 [ $obf_mode -eq $new_obf_mode ] ||
17079                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17080
17081                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17082                 chmod $old_obf_mode $DIR/.lustre/fid ||
17083                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17084         fi
17085
17086         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17087         fid=$($LFS path2fid $test_dir/$tfile-2)
17088
17089         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17090         then # LU-5424
17091                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17092                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17093                         error "create lov data thru .lustre failed"
17094         fi
17095         echo "cp /etc/passwd $test_dir/$tfile-2"
17096         cp /etc/passwd $test_dir/$tfile-2 ||
17097                 error "copy to $test_dir/$tfile-2 failed."
17098         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17099         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17100                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17101
17102         rm -rf $test_dir/tfile.lnk
17103         rm -rf $test_dir/$tfile-2
17104 }
17105
17106 test_154A() {
17107         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17108                 skip "Need MDS version at least 2.4.1"
17109
17110         local tf=$DIR/$tfile
17111         touch $tf
17112
17113         local fid=$($LFS path2fid $tf)
17114         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17115
17116         # check that we get the same pathname back
17117         local rootpath
17118         local found
17119         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17120                 echo "$rootpath $fid"
17121                 found=$($LFS fid2path $rootpath "$fid")
17122                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17123                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17124         done
17125
17126         # check wrong root path format
17127         rootpath=$MOUNT"_wrong"
17128         found=$($LFS fid2path $rootpath "$fid")
17129         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17130 }
17131 run_test 154A "lfs path2fid and fid2path basic checks"
17132
17133 test_154B() {
17134         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17135                 skip "Need MDS version at least 2.4.1"
17136
17137         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17138         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17139         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17140         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17141
17142         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17143         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17144
17145         # check that we get the same pathname
17146         echo "PFID: $PFID, name: $name"
17147         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17148         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17149         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17150                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17151
17152         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17153 }
17154 run_test 154B "verify the ll_decode_linkea tool"
17155
17156 test_154a() {
17157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17158         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17159         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17160                 skip "Need MDS version at least 2.2.51"
17161         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17162
17163         cp /etc/hosts $DIR/$tfile
17164
17165         fid=$($LFS path2fid $DIR/$tfile)
17166         rc=$?
17167         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17168
17169         dot_lustre_fid_permission_check "$fid" $DIR ||
17170                 error "dot lustre permission check $fid failed"
17171
17172         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17173
17174         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17175
17176         touch $MOUNT/.lustre/file &&
17177                 error "creation is not allowed under .lustre"
17178
17179         mkdir $MOUNT/.lustre/dir &&
17180                 error "mkdir is not allowed under .lustre"
17181
17182         rm -rf $DIR/$tfile
17183 }
17184 run_test 154a "Open-by-FID"
17185
17186 test_154b() {
17187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17188         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17190         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17191                 skip "Need MDS version at least 2.2.51"
17192
17193         local remote_dir=$DIR/$tdir/remote_dir
17194         local MDTIDX=1
17195         local rc=0
17196
17197         mkdir -p $DIR/$tdir
17198         $LFS mkdir -i $MDTIDX $remote_dir ||
17199                 error "create remote directory failed"
17200
17201         cp /etc/hosts $remote_dir/$tfile
17202
17203         fid=$($LFS path2fid $remote_dir/$tfile)
17204         rc=$?
17205         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17206
17207         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17208                 error "dot lustre permission check $fid failed"
17209         rm -rf $DIR/$tdir
17210 }
17211 run_test 154b "Open-by-FID for remote directory"
17212
17213 test_154c() {
17214         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17215                 skip "Need MDS version at least 2.4.1"
17216
17217         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17218         local FID1=$($LFS path2fid $DIR/$tfile.1)
17219         local FID2=$($LFS path2fid $DIR/$tfile.2)
17220         local FID3=$($LFS path2fid $DIR/$tfile.3)
17221
17222         local N=1
17223         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17224                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17225                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17226                 local want=FID$N
17227                 [ "$FID" = "${!want}" ] ||
17228                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17229                 N=$((N + 1))
17230         done
17231
17232         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17233         do
17234                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17235                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17236                 N=$((N + 1))
17237         done
17238 }
17239 run_test 154c "lfs path2fid and fid2path multiple arguments"
17240
17241 test_154d() {
17242         remote_mds_nodsh && skip "remote MDS with nodsh"
17243         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17244                 skip "Need MDS version at least 2.5.53"
17245
17246         if remote_mds; then
17247                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17248         else
17249                 nid="0@lo"
17250         fi
17251         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17252         local fd
17253         local cmd
17254
17255         rm -f $DIR/$tfile
17256         touch $DIR/$tfile
17257
17258         local fid=$($LFS path2fid $DIR/$tfile)
17259         # Open the file
17260         fd=$(free_fd)
17261         cmd="exec $fd<$DIR/$tfile"
17262         eval $cmd
17263         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17264         echo "$fid_list" | grep "$fid"
17265         rc=$?
17266
17267         cmd="exec $fd>/dev/null"
17268         eval $cmd
17269         if [ $rc -ne 0 ]; then
17270                 error "FID $fid not found in open files list $fid_list"
17271         fi
17272 }
17273 run_test 154d "Verify open file fid"
17274
17275 test_154e()
17276 {
17277         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17278                 skip "Need MDS version at least 2.6.50"
17279
17280         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17281                 error ".lustre returned by readdir"
17282         fi
17283 }
17284 run_test 154e ".lustre is not returned by readdir"
17285
17286 test_154f() {
17287         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17288
17289         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17290         mkdir_on_mdt0 $DIR/$tdir
17291         # test dirs inherit from its stripe
17292         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17293         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17294         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17295         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17296         touch $DIR/f
17297
17298         # get fid of parents
17299         local FID0=$($LFS path2fid $DIR/$tdir)
17300         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17301         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17302         local FID3=$($LFS path2fid $DIR)
17303
17304         # check that path2fid --parents returns expected <parent_fid>/name
17305         # 1) test for a directory (single parent)
17306         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17307         [ "$parent" == "$FID0/foo1" ] ||
17308                 error "expected parent: $FID0/foo1, got: $parent"
17309
17310         # 2) test for a file with nlink > 1 (multiple parents)
17311         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17312         echo "$parent" | grep -F "$FID1/$tfile" ||
17313                 error "$FID1/$tfile not returned in parent list"
17314         echo "$parent" | grep -F "$FID2/link" ||
17315                 error "$FID2/link not returned in parent list"
17316
17317         # 3) get parent by fid
17318         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17319         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17320         echo "$parent" | grep -F "$FID1/$tfile" ||
17321                 error "$FID1/$tfile not returned in parent list (by fid)"
17322         echo "$parent" | grep -F "$FID2/link" ||
17323                 error "$FID2/link not returned in parent list (by fid)"
17324
17325         # 4) test for entry in root directory
17326         parent=$($LFS path2fid --parents $DIR/f)
17327         echo "$parent" | grep -F "$FID3/f" ||
17328                 error "$FID3/f not returned in parent list"
17329
17330         # 5) test it on root directory
17331         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17332                 error "$MOUNT should not have parents"
17333
17334         # enable xattr caching and check that linkea is correctly updated
17335         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17336         save_lustre_params client "llite.*.xattr_cache" > $save
17337         lctl set_param llite.*.xattr_cache 1
17338
17339         # 6.1) linkea update on rename
17340         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17341
17342         # get parents by fid
17343         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17344         # foo1 should no longer be returned in parent list
17345         echo "$parent" | grep -F "$FID1" &&
17346                 error "$FID1 should no longer be in parent list"
17347         # the new path should appear
17348         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17349                 error "$FID2/$tfile.moved is not in parent list"
17350
17351         # 6.2) linkea update on unlink
17352         rm -f $DIR/$tdir/foo2/link
17353         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17354         # foo2/link should no longer be returned in parent list
17355         echo "$parent" | grep -F "$FID2/link" &&
17356                 error "$FID2/link should no longer be in parent list"
17357         true
17358
17359         rm -f $DIR/f
17360         restore_lustre_params < $save
17361         rm -f $save
17362 }
17363 run_test 154f "get parent fids by reading link ea"
17364
17365 test_154g()
17366 {
17367         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17368            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17369                 skip "Need MDS version at least 2.6.92"
17370
17371         mkdir_on_mdt0 $DIR/$tdir
17372         llapi_fid_test -d $DIR/$tdir
17373 }
17374 run_test 154g "various llapi FID tests"
17375
17376 test_154h()
17377 {
17378         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17379                 skip "Need client at least version 2.15.55.1"
17380
17381         # Create an empty file
17382         touch $DIR/$tfile
17383
17384         # Get FID (interactive mode) and save under $TMP/$tfile.log
17385         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17386                 path2fid $DIR/$tfile
17387         EOF
17388
17389         fid=$(cat $TMP/$tfile.log)
17390         # $fid should not be empty
17391         [[ ! -z $fid ]] || error "FID is empty"
17392         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17393 }
17394 run_test 154h "Verify interactive path2fid"
17395
17396 test_155_small_load() {
17397     local temp=$TMP/$tfile
17398     local file=$DIR/$tfile
17399
17400     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17401         error "dd of=$temp bs=6096 count=1 failed"
17402     cp $temp $file
17403     cancel_lru_locks $OSC
17404     cmp $temp $file || error "$temp $file differ"
17405
17406     $TRUNCATE $temp 6000
17407     $TRUNCATE $file 6000
17408     cmp $temp $file || error "$temp $file differ (truncate1)"
17409
17410     echo "12345" >>$temp
17411     echo "12345" >>$file
17412     cmp $temp $file || error "$temp $file differ (append1)"
17413
17414     echo "12345" >>$temp
17415     echo "12345" >>$file
17416     cmp $temp $file || error "$temp $file differ (append2)"
17417
17418     rm -f $temp $file
17419     true
17420 }
17421
17422 test_155_big_load() {
17423         remote_ost_nodsh && skip "remote OST with nodsh"
17424
17425         local temp=$TMP/$tfile
17426         local file=$DIR/$tfile
17427
17428         free_min_max
17429         local cache_size=$(do_facet ost$((MAXI+1)) \
17430                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17431
17432         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17433         # pre-set value
17434         if [ -z "$cache_size" ]; then
17435                 cache_size=256
17436         fi
17437         local large_file_size=$((cache_size * 2))
17438
17439         echo "OSS cache size: $cache_size KB"
17440         echo "Large file size: $large_file_size KB"
17441
17442         [ $MAXV -le $large_file_size ] &&
17443                 skip_env "max available OST size needs > $large_file_size KB"
17444
17445         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17446
17447         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17448                 error "dd of=$temp bs=$large_file_size count=1k failed"
17449         cp $temp $file
17450         ls -lh $temp $file
17451         cancel_lru_locks osc
17452         cmp $temp $file || error "$temp $file differ"
17453
17454         rm -f $temp $file
17455         true
17456 }
17457
17458 save_writethrough() {
17459         local facets=$(get_facets OST)
17460
17461         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17462 }
17463
17464 test_155a() {
17465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17466
17467         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17468
17469         save_writethrough $p
17470
17471         set_cache read on
17472         set_cache writethrough on
17473         test_155_small_load
17474         restore_lustre_params < $p
17475         rm -f $p
17476 }
17477 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17478
17479 test_155b() {
17480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17481
17482         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17483
17484         save_writethrough $p
17485
17486         set_cache read on
17487         set_cache writethrough off
17488         test_155_small_load
17489         restore_lustre_params < $p
17490         rm -f $p
17491 }
17492 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17493
17494 test_155c() {
17495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17496
17497         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17498
17499         save_writethrough $p
17500
17501         set_cache read off
17502         set_cache writethrough on
17503         test_155_small_load
17504         restore_lustre_params < $p
17505         rm -f $p
17506 }
17507 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17508
17509 test_155d() {
17510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17511
17512         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17513
17514         save_writethrough $p
17515
17516         set_cache read off
17517         set_cache writethrough off
17518         test_155_small_load
17519         restore_lustre_params < $p
17520         rm -f $p
17521 }
17522 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17523
17524 test_155e() {
17525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17526
17527         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17528
17529         save_writethrough $p
17530
17531         set_cache read on
17532         set_cache writethrough on
17533         test_155_big_load
17534         restore_lustre_params < $p
17535         rm -f $p
17536 }
17537 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17538
17539 test_155f() {
17540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17541
17542         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17543
17544         save_writethrough $p
17545
17546         set_cache read on
17547         set_cache writethrough off
17548         test_155_big_load
17549         restore_lustre_params < $p
17550         rm -f $p
17551 }
17552 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17553
17554 test_155g() {
17555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17556
17557         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17558
17559         save_writethrough $p
17560
17561         set_cache read off
17562         set_cache writethrough on
17563         test_155_big_load
17564         restore_lustre_params < $p
17565         rm -f $p
17566 }
17567 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17568
17569 test_155h() {
17570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17571
17572         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17573
17574         save_writethrough $p
17575
17576         set_cache read off
17577         set_cache writethrough off
17578         test_155_big_load
17579         restore_lustre_params < $p
17580         rm -f $p
17581 }
17582 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17583
17584 test_156() {
17585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17586         remote_ost_nodsh && skip "remote OST with nodsh"
17587         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17588                 skip "stats not implemented on old servers"
17589         [ "$ost1_FSTYPE" = "zfs" ] &&
17590                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17591         (( CLIENT_VERSION == OST1_VERSION )) ||
17592                 skip "LU-13081: no interop testing for OSS cache"
17593
17594         local CPAGES=3
17595         local BEFORE
17596         local AFTER
17597         local file="$DIR/$tfile"
17598         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17599
17600         save_writethrough $p
17601         roc_hit_init
17602
17603         log "Turn on read and write cache"
17604         set_cache read on
17605         set_cache writethrough on
17606
17607         log "Write data and read it back."
17608         log "Read should be satisfied from the cache."
17609         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17610         BEFORE=$(roc_hit)
17611         cancel_lru_locks osc
17612         cat $file >/dev/null
17613         AFTER=$(roc_hit)
17614         if ! let "AFTER - BEFORE == CPAGES"; then
17615                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17616         else
17617                 log "cache hits: before: $BEFORE, after: $AFTER"
17618         fi
17619
17620         log "Read again; it should be satisfied from the cache."
17621         BEFORE=$AFTER
17622         cancel_lru_locks osc
17623         cat $file >/dev/null
17624         AFTER=$(roc_hit)
17625         if ! let "AFTER - BEFORE == CPAGES"; then
17626                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17627         else
17628                 log "cache hits:: before: $BEFORE, after: $AFTER"
17629         fi
17630
17631         log "Turn off the read cache and turn on the write cache"
17632         set_cache read off
17633         set_cache writethrough on
17634
17635         log "Read again; it should be satisfied from the cache."
17636         BEFORE=$(roc_hit)
17637         cancel_lru_locks osc
17638         cat $file >/dev/null
17639         AFTER=$(roc_hit)
17640         if ! let "AFTER - BEFORE == CPAGES"; then
17641                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17642         else
17643                 log "cache hits:: before: $BEFORE, after: $AFTER"
17644         fi
17645
17646         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17647                 # > 2.12.56 uses pagecache if cached
17648                 log "Read again; it should not be satisfied from the cache."
17649                 BEFORE=$AFTER
17650                 cancel_lru_locks osc
17651                 cat $file >/dev/null
17652                 AFTER=$(roc_hit)
17653                 if ! let "AFTER - BEFORE == 0"; then
17654                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17655                 else
17656                         log "cache hits:: before: $BEFORE, after: $AFTER"
17657                 fi
17658         fi
17659
17660         log "Write data and read it back."
17661         log "Read should be satisfied from the cache."
17662         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17663         BEFORE=$(roc_hit)
17664         cancel_lru_locks osc
17665         cat $file >/dev/null
17666         AFTER=$(roc_hit)
17667         if ! let "AFTER - BEFORE == CPAGES"; then
17668                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17669         else
17670                 log "cache hits:: before: $BEFORE, after: $AFTER"
17671         fi
17672
17673         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17674                 # > 2.12.56 uses pagecache if cached
17675                 log "Read again; it should not be satisfied from the cache."
17676                 BEFORE=$AFTER
17677                 cancel_lru_locks osc
17678                 cat $file >/dev/null
17679                 AFTER=$(roc_hit)
17680                 if ! let "AFTER - BEFORE == 0"; then
17681                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17682                 else
17683                         log "cache hits:: before: $BEFORE, after: $AFTER"
17684                 fi
17685         fi
17686
17687         log "Turn off read and write cache"
17688         set_cache read off
17689         set_cache writethrough off
17690
17691         log "Write data and read it back"
17692         log "It should not be satisfied from the cache."
17693         rm -f $file
17694         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17695         cancel_lru_locks osc
17696         BEFORE=$(roc_hit)
17697         cat $file >/dev/null
17698         AFTER=$(roc_hit)
17699         if ! let "AFTER - BEFORE == 0"; then
17700                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17701         else
17702                 log "cache hits:: before: $BEFORE, after: $AFTER"
17703         fi
17704
17705         log "Turn on the read cache and turn off the write cache"
17706         set_cache read on
17707         set_cache writethrough off
17708
17709         log "Write data and read it back"
17710         log "It should not be satisfied from the cache."
17711         rm -f $file
17712         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17713         BEFORE=$(roc_hit)
17714         cancel_lru_locks osc
17715         cat $file >/dev/null
17716         AFTER=$(roc_hit)
17717         if ! let "AFTER - BEFORE == 0"; then
17718                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17719         else
17720                 log "cache hits:: before: $BEFORE, after: $AFTER"
17721         fi
17722
17723         log "Read again; it should be satisfied from the cache."
17724         BEFORE=$(roc_hit)
17725         cancel_lru_locks osc
17726         cat $file >/dev/null
17727         AFTER=$(roc_hit)
17728         if ! let "AFTER - BEFORE == CPAGES"; then
17729                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17730         else
17731                 log "cache hits:: before: $BEFORE, after: $AFTER"
17732         fi
17733
17734         restore_lustre_params < $p
17735         rm -f $p $file
17736 }
17737 run_test 156 "Verification of tunables"
17738
17739 test_160a() {
17740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17741         remote_mds_nodsh && skip "remote MDS with nodsh"
17742         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17743                 skip "Need MDS version at least 2.2.0"
17744
17745         changelog_register || error "changelog_register failed"
17746         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17747         changelog_users $SINGLEMDS | grep -q $cl_user ||
17748                 error "User $cl_user not found in changelog_users"
17749
17750         mkdir_on_mdt0 $DIR/$tdir
17751
17752         # change something
17753         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17754         changelog_clear 0 || error "changelog_clear failed"
17755         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17756         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17757         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17758         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17759         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17760         rm $DIR/$tdir/pics/desktop.jpg
17761
17762         echo "verifying changelog mask"
17763         changelog_chmask "-MKDIR"
17764         changelog_chmask "-CLOSE"
17765
17766         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17767         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17768
17769         changelog_chmask "+MKDIR"
17770         changelog_chmask "+CLOSE"
17771
17772         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17773         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17774
17775         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17776         CLOSES=$(changelog_dump | grep -c "CLOSE")
17777         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17778         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17779
17780         # verify contents
17781         echo "verifying target fid"
17782         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17783         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17784         [ "$fidc" == "$fidf" ] ||
17785                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17786         echo "verifying parent fid"
17787         # The FID returned from the Changelog may be the directory shard on
17788         # a different MDT, and not the FID returned by path2fid on the parent.
17789         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17790         # since this is what will matter when recreating this file in the tree.
17791         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17792         local pathp=$($LFS fid2path $MOUNT "$fidp")
17793         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17794                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17795
17796         echo "getting records for $cl_user"
17797         changelog_users $SINGLEMDS
17798         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17799         local nclr=3
17800         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17801                 error "changelog_clear failed"
17802         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17803         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17804         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17805                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17806
17807         local min0_rec=$(changelog_users $SINGLEMDS |
17808                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17809         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17810                           awk '{ print $1; exit; }')
17811
17812         changelog_dump | tail -n 5
17813         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17814         [ $first_rec == $((min0_rec + 1)) ] ||
17815                 error "first index should be $min0_rec + 1 not $first_rec"
17816
17817         # LU-3446 changelog index reset on MDT restart
17818         local cur_rec1=$(changelog_users $SINGLEMDS |
17819                          awk '/^current.index:/ { print $NF }')
17820         changelog_clear 0 ||
17821                 error "clear all changelog records for $cl_user failed"
17822         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17823         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17824                 error "Fail to start $SINGLEMDS"
17825         local cur_rec2=$(changelog_users $SINGLEMDS |
17826                          awk '/^current.index:/ { print $NF }')
17827         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17828         [ $cur_rec1 == $cur_rec2 ] ||
17829                 error "current index should be $cur_rec1 not $cur_rec2"
17830
17831         echo "verifying users from this test are deregistered"
17832         changelog_deregister || error "changelog_deregister failed"
17833         changelog_users $SINGLEMDS | grep -q $cl_user &&
17834                 error "User '$cl_user' still in changelog_users"
17835
17836         # lctl get_param -n mdd.*.changelog_users
17837         # current_index: 144
17838         # ID    index (idle seconds)
17839         # cl3   144   (2) mask=<list>
17840         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17841                 # this is the normal case where all users were deregistered
17842                 # make sure no new records are added when no users are present
17843                 local last_rec1=$(changelog_users $SINGLEMDS |
17844                                   awk '/^current.index:/ { print $NF }')
17845                 touch $DIR/$tdir/chloe
17846                 local last_rec2=$(changelog_users $SINGLEMDS |
17847                                   awk '/^current.index:/ { print $NF }')
17848                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17849                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17850         else
17851                 # any changelog users must be leftovers from a previous test
17852                 changelog_users $SINGLEMDS
17853                 echo "other changelog users; can't verify off"
17854         fi
17855 }
17856 run_test 160a "changelog sanity"
17857
17858 test_160b() { # LU-3587
17859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17860         remote_mds_nodsh && skip "remote MDS with nodsh"
17861         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17862                 skip "Need MDS version at least 2.2.0"
17863
17864         changelog_register || error "changelog_register failed"
17865         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17866         changelog_users $SINGLEMDS | grep -q $cl_user ||
17867                 error "User '$cl_user' not found in changelog_users"
17868
17869         local longname1=$(str_repeat a 255)
17870         local longname2=$(str_repeat b 255)
17871
17872         cd $DIR
17873         echo "creating very long named file"
17874         touch $longname1 || error "create of '$longname1' failed"
17875         echo "renaming very long named file"
17876         mv $longname1 $longname2
17877
17878         changelog_dump | grep RENME | tail -n 5
17879         rm -f $longname2
17880 }
17881 run_test 160b "Verify that very long rename doesn't crash in changelog"
17882
17883 test_160c() {
17884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17885         remote_mds_nodsh && skip "remote MDS with nodsh"
17886
17887         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17888                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17889                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17890                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17891
17892         local rc=0
17893
17894         # Registration step
17895         changelog_register || error "changelog_register failed"
17896
17897         rm -rf $DIR/$tdir
17898         mkdir -p $DIR/$tdir
17899         $MCREATE $DIR/$tdir/foo_160c
17900         changelog_chmask "-TRUNC"
17901         $TRUNCATE $DIR/$tdir/foo_160c 200
17902         changelog_chmask "+TRUNC"
17903         $TRUNCATE $DIR/$tdir/foo_160c 199
17904         changelog_dump | tail -n 5
17905         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17906         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17907 }
17908 run_test 160c "verify that changelog log catch the truncate event"
17909
17910 test_160d() {
17911         remote_mds_nodsh && skip "remote MDS with nodsh"
17912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17914         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17915                 skip "Need MDS version at least 2.7.60"
17916
17917         # Registration step
17918         changelog_register || error "changelog_register failed"
17919
17920         mkdir -p $DIR/$tdir/migrate_dir
17921         changelog_clear 0 || error "changelog_clear failed"
17922
17923         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17924         changelog_dump | tail -n 5
17925         local migrates=$(changelog_dump | grep -c "MIGRT")
17926         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17927 }
17928 run_test 160d "verify that changelog log catch the migrate event"
17929
17930 test_160e() {
17931         remote_mds_nodsh && skip "remote MDS with nodsh"
17932
17933         # Create a user
17934         changelog_register || error "changelog_register failed"
17935
17936         local MDT0=$(facet_svc $SINGLEMDS)
17937         local rc
17938
17939         # No user (expect fail)
17940         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17941         rc=$?
17942         if [ $rc -eq 0 ]; then
17943                 error "Should fail without user"
17944         elif [ $rc -ne 4 ]; then
17945                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17946         fi
17947
17948         # Delete a future user (expect fail)
17949         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17950         rc=$?
17951         if [ $rc -eq 0 ]; then
17952                 error "Deleted non-existant user cl77"
17953         elif [ $rc -ne 2 ]; then
17954                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17955         fi
17956
17957         # Clear to a bad index (1 billion should be safe)
17958         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17959         rc=$?
17960
17961         if [ $rc -eq 0 ]; then
17962                 error "Successfully cleared to invalid CL index"
17963         elif [ $rc -ne 22 ]; then
17964                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17965         fi
17966 }
17967 run_test 160e "changelog negative testing (should return errors)"
17968
17969 test_160f() {
17970         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17971         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17972                 skip "Need MDS version at least 2.10.56"
17973
17974         local mdts=$(comma_list $(mdts_nodes))
17975
17976         # Create a user
17977         changelog_register || error "first changelog_register failed"
17978         changelog_register || error "second changelog_register failed"
17979         local cl_users
17980         declare -A cl_user1
17981         declare -A cl_user2
17982         local user_rec1
17983         local user_rec2
17984         local i
17985
17986         # generate some changelog records to accumulate on each MDT
17987         # use all_char because created files should be evenly distributed
17988         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17989                 error "test_mkdir $tdir failed"
17990         log "$(date +%s): creating first files"
17991         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17992                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17993                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17994         done
17995
17996         # check changelogs have been generated
17997         local start=$SECONDS
17998         local idle_time=$((MDSCOUNT * 5 + 5))
17999         local nbcl=$(changelog_dump | wc -l)
18000         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18001
18002         for param in "changelog_max_idle_time=$idle_time" \
18003                      "changelog_gc=1" \
18004                      "changelog_min_gc_interval=2" \
18005                      "changelog_min_free_cat_entries=3"; do
18006                 local MDT0=$(facet_svc $SINGLEMDS)
18007                 local var="${param%=*}"
18008                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18009
18010                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18011                 do_nodes $mdts $LCTL set_param mdd.*.$param
18012         done
18013
18014         # force cl_user2 to be idle (1st part), but also cancel the
18015         # cl_user1 records so that it is not evicted later in the test.
18016         local sleep1=$((idle_time / 2))
18017         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
18018         sleep $sleep1
18019
18020         # simulate changelog catalog almost full
18021         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
18022         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
18023
18024         for i in $(seq $MDSCOUNT); do
18025                 cl_users=(${CL_USERS[mds$i]})
18026                 cl_user1[mds$i]="${cl_users[0]}"
18027                 cl_user2[mds$i]="${cl_users[1]}"
18028
18029                 [ -n "${cl_user1[mds$i]}" ] ||
18030                         error "mds$i: no user registered"
18031                 [ -n "${cl_user2[mds$i]}" ] ||
18032                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18033
18034                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18035                 [ -n "$user_rec1" ] ||
18036                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18037                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18038                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18039                 [ -n "$user_rec2" ] ||
18040                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18041                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18042                      "$user_rec1 + 2 == $user_rec2"
18043                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18044                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18045                               "$user_rec1 + 2, but is $user_rec2"
18046                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18047                 [ -n "$user_rec2" ] ||
18048                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18049                 [ $user_rec1 == $user_rec2 ] ||
18050                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18051                               "$user_rec1, but is $user_rec2"
18052         done
18053
18054         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18055         local sleep2=$((idle_time - (SECONDS - start) + 1))
18056         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18057         sleep $sleep2
18058
18059         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18060         # cl_user1 should be OK because it recently processed records.
18061         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18062         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18063                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18064                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18065         done
18066
18067         # ensure gc thread is done
18068         for i in $(mdts_nodes); do
18069                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18070                         error "$i: GC-thread not done"
18071         done
18072
18073         local first_rec
18074         for (( i = 1; i <= MDSCOUNT; i++ )); do
18075                 # check cl_user1 still registered
18076                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18077                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18078                 # check cl_user2 unregistered
18079                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18080                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18081
18082                 # check changelogs are present and starting at $user_rec1 + 1
18083                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18084                 [ -n "$user_rec1" ] ||
18085                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18086                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18087                             awk '{ print $1; exit; }')
18088
18089                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18090                 [ $((user_rec1 + 1)) == $first_rec ] ||
18091                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18092         done
18093 }
18094 run_test 160f "changelog garbage collect (timestamped users)"
18095
18096 test_160g() {
18097         remote_mds_nodsh && skip "remote MDS with nodsh"
18098         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18099                 skip "Need MDS version at least 2.14.55"
18100
18101         local mdts=$(comma_list $(mdts_nodes))
18102
18103         # Create a user
18104         changelog_register || error "first changelog_register failed"
18105         changelog_register || error "second changelog_register failed"
18106         local cl_users
18107         declare -A cl_user1
18108         declare -A cl_user2
18109         local user_rec1
18110         local user_rec2
18111         local i
18112
18113         # generate some changelog records to accumulate on each MDT
18114         # use all_char because created files should be evenly distributed
18115         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18116                 error "test_mkdir $tdir failed"
18117         for ((i = 0; i < MDSCOUNT; i++)); do
18118                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18119                         error "create $DIR/$tdir/d$i.1 failed"
18120         done
18121
18122         # check changelogs have been generated
18123         local nbcl=$(changelog_dump | wc -l)
18124         (( $nbcl > 0 )) || error "no changelogs found"
18125
18126         # reduce the max_idle_indexes value to make sure we exceed it
18127         for param in "changelog_max_idle_indexes=2" \
18128                      "changelog_gc=1" \
18129                      "changelog_min_gc_interval=2"; do
18130                 local MDT0=$(facet_svc $SINGLEMDS)
18131                 local var="${param%=*}"
18132                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18133
18134                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18135                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18136                         error "unable to set mdd.*.$param"
18137         done
18138
18139         local start=$SECONDS
18140         for i in $(seq $MDSCOUNT); do
18141                 cl_users=(${CL_USERS[mds$i]})
18142                 cl_user1[mds$i]="${cl_users[0]}"
18143                 cl_user2[mds$i]="${cl_users[1]}"
18144
18145                 [ -n "${cl_user1[mds$i]}" ] ||
18146                         error "mds$i: user1 is not registered"
18147                 [ -n "${cl_user2[mds$i]}" ] ||
18148                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18149
18150                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18151                 [ -n "$user_rec1" ] ||
18152                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18153                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18154                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18155                 [ -n "$user_rec2" ] ||
18156                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18157                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18158                      "$user_rec1 + 2 == $user_rec2"
18159                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18160                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18161                               "expected $user_rec1 + 2, but is $user_rec2"
18162                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18163                 [ -n "$user_rec2" ] ||
18164                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18165                 [ $user_rec1 == $user_rec2 ] ||
18166                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18167                               "expected $user_rec1, but is $user_rec2"
18168         done
18169
18170         # ensure we are past the previous changelog_min_gc_interval set above
18171         local sleep2=$((start + 2 - SECONDS))
18172         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18173         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18174         # cl_user1 should be OK because it recently processed records.
18175         for ((i = 0; i < MDSCOUNT; i++)); do
18176                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18177                         error "create $DIR/$tdir/d$i.3 failed"
18178         done
18179
18180         # ensure gc thread is done
18181         for i in $(mdts_nodes); do
18182                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18183                         error "$i: GC-thread not done"
18184         done
18185
18186         local first_rec
18187         for (( i = 1; i <= MDSCOUNT; i++ )); do
18188                 # check cl_user1 still registered
18189                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18190                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18191                 # check cl_user2 unregistered
18192                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18193                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18194
18195                 # check changelogs are present and starting at $user_rec1 + 1
18196                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18197                 [ -n "$user_rec1" ] ||
18198                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18199                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18200                             awk '{ print $1; exit; }')
18201
18202                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18203                 [ $((user_rec1 + 1)) == $first_rec ] ||
18204                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18205         done
18206 }
18207 run_test 160g "changelog garbage collect on idle records"
18208
18209 test_160h() {
18210         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18211         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18212                 skip "Need MDS version at least 2.10.56"
18213
18214         local mdts=$(comma_list $(mdts_nodes))
18215
18216         # Create a user
18217         changelog_register || error "first changelog_register failed"
18218         changelog_register || error "second changelog_register failed"
18219         local cl_users
18220         declare -A cl_user1
18221         declare -A cl_user2
18222         local user_rec1
18223         local user_rec2
18224         local i
18225
18226         # generate some changelog records to accumulate on each MDT
18227         # use all_char because created files should be evenly distributed
18228         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18229                 error "test_mkdir $tdir failed"
18230         for ((i = 0; i < MDSCOUNT; i++)); do
18231                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18232                         error "create $DIR/$tdir/d$i.1 failed"
18233         done
18234
18235         # check changelogs have been generated
18236         local nbcl=$(changelog_dump | wc -l)
18237         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18238
18239         for param in "changelog_max_idle_time=10" \
18240                      "changelog_gc=1" \
18241                      "changelog_min_gc_interval=2"; do
18242                 local MDT0=$(facet_svc $SINGLEMDS)
18243                 local var="${param%=*}"
18244                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18245
18246                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18247                 do_nodes $mdts $LCTL set_param mdd.*.$param
18248         done
18249
18250         # force cl_user2 to be idle (1st part)
18251         sleep 9
18252
18253         for i in $(seq $MDSCOUNT); do
18254                 cl_users=(${CL_USERS[mds$i]})
18255                 cl_user1[mds$i]="${cl_users[0]}"
18256                 cl_user2[mds$i]="${cl_users[1]}"
18257
18258                 [ -n "${cl_user1[mds$i]}" ] ||
18259                         error "mds$i: no user registered"
18260                 [ -n "${cl_user2[mds$i]}" ] ||
18261                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18262
18263                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18264                 [ -n "$user_rec1" ] ||
18265                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18266                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18267                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18268                 [ -n "$user_rec2" ] ||
18269                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18270                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18271                      "$user_rec1 + 2 == $user_rec2"
18272                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18273                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18274                               "$user_rec1 + 2, but is $user_rec2"
18275                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18276                 [ -n "$user_rec2" ] ||
18277                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18278                 [ $user_rec1 == $user_rec2 ] ||
18279                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18280                               "$user_rec1, but is $user_rec2"
18281         done
18282
18283         # force cl_user2 to be idle (2nd part) and to reach
18284         # changelog_max_idle_time
18285         sleep 2
18286
18287         # force each GC-thread start and block then
18288         # one per MDT/MDD, set fail_val accordingly
18289         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18290         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18291
18292         # generate more changelogs to trigger fail_loc
18293         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18294                 error "create $DIR/$tdir/${tfile}bis failed"
18295
18296         # stop MDT to stop GC-thread, should be done in back-ground as it will
18297         # block waiting for the thread to be released and exit
18298         declare -A stop_pids
18299         for i in $(seq $MDSCOUNT); do
18300                 stop mds$i &
18301                 stop_pids[mds$i]=$!
18302         done
18303
18304         for i in $(mdts_nodes); do
18305                 local facet
18306                 local nb=0
18307                 local facets=$(facets_up_on_host $i)
18308
18309                 for facet in ${facets//,/ }; do
18310                         if [[ $facet == mds* ]]; then
18311                                 nb=$((nb + 1))
18312                         fi
18313                 done
18314                 # ensure each MDS's gc threads are still present and all in "R"
18315                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18316                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18317                         error "$i: expected $nb GC-thread"
18318                 wait_update $i \
18319                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18320                         "R" 20 ||
18321                         error "$i: GC-thread not found in R-state"
18322                 # check umounts of each MDT on MDS have reached kthread_stop()
18323                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18324                         error "$i: expected $nb umount"
18325                 wait_update $i \
18326                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18327                         error "$i: umount not found in D-state"
18328         done
18329
18330         # release all GC-threads
18331         do_nodes $mdts $LCTL set_param fail_loc=0
18332
18333         # wait for MDT stop to complete
18334         for i in $(seq $MDSCOUNT); do
18335                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18336         done
18337
18338         # XXX
18339         # may try to check if any orphan changelog records are present
18340         # via ldiskfs/zfs and llog_reader...
18341
18342         # re-start/mount MDTs
18343         for i in $(seq $MDSCOUNT); do
18344                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18345                         error "Fail to start mds$i"
18346         done
18347
18348         local first_rec
18349         for i in $(seq $MDSCOUNT); do
18350                 # check cl_user1 still registered
18351                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18352                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18353                 # check cl_user2 unregistered
18354                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18355                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18356
18357                 # check changelogs are present and starting at $user_rec1 + 1
18358                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18359                 [ -n "$user_rec1" ] ||
18360                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18361                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18362                             awk '{ print $1; exit; }')
18363
18364                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18365                 [ $((user_rec1 + 1)) == $first_rec ] ||
18366                         error "mds$i: first index should be $user_rec1 + 1, " \
18367                               "but is $first_rec"
18368         done
18369 }
18370 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18371               "during mount"
18372
18373 test_160i() {
18374
18375         local mdts=$(comma_list $(mdts_nodes))
18376
18377         changelog_register || error "first changelog_register failed"
18378
18379         # generate some changelog records to accumulate on each MDT
18380         # use all_char because created files should be evenly distributed
18381         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18382                 error "test_mkdir $tdir failed"
18383         for ((i = 0; i < MDSCOUNT; i++)); do
18384                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18385                         error "create $DIR/$tdir/d$i.1 failed"
18386         done
18387
18388         # check changelogs have been generated
18389         local nbcl=$(changelog_dump | wc -l)
18390         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18391
18392         # simulate race between register and unregister
18393         # XXX as fail_loc is set per-MDS, with DNE configs the race
18394         # simulation will only occur for one MDT per MDS and for the
18395         # others the normal race scenario will take place
18396         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18397         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18398         do_nodes $mdts $LCTL set_param fail_val=1
18399
18400         # unregister 1st user
18401         changelog_deregister &
18402         local pid1=$!
18403         # wait some time for deregister work to reach race rdv
18404         sleep 2
18405         # register 2nd user
18406         changelog_register || error "2nd user register failed"
18407
18408         wait $pid1 || error "1st user deregister failed"
18409
18410         local i
18411         local last_rec
18412         declare -A LAST_REC
18413         for i in $(seq $MDSCOUNT); do
18414                 if changelog_users mds$i | grep "^cl"; then
18415                         # make sure new records are added with one user present
18416                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18417                                           awk '/^current.index:/ { print $NF }')
18418                 else
18419                         error "mds$i has no user registered"
18420                 fi
18421         done
18422
18423         # generate more changelog records to accumulate on each MDT
18424         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18425                 error "create $DIR/$tdir/${tfile}bis failed"
18426
18427         for i in $(seq $MDSCOUNT); do
18428                 last_rec=$(changelog_users $SINGLEMDS |
18429                            awk '/^current.index:/ { print $NF }')
18430                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18431                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18432                         error "changelogs are off on mds$i"
18433         done
18434 }
18435 run_test 160i "changelog user register/unregister race"
18436
18437 test_160j() {
18438         remote_mds_nodsh && skip "remote MDS with nodsh"
18439         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18440                 skip "Need MDS version at least 2.12.56"
18441
18442         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18443         stack_trap "umount $MOUNT2" EXIT
18444
18445         changelog_register || error "first changelog_register failed"
18446         stack_trap "changelog_deregister" EXIT
18447
18448         # generate some changelog
18449         # use all_char because created files should be evenly distributed
18450         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18451                 error "mkdir $tdir failed"
18452         for ((i = 0; i < MDSCOUNT; i++)); do
18453                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18454                         error "create $DIR/$tdir/d$i.1 failed"
18455         done
18456
18457         # open the changelog device
18458         exec 3>/dev/changelog-$FSNAME-MDT0000
18459         stack_trap "exec 3>&-" EXIT
18460         exec 4</dev/changelog-$FSNAME-MDT0000
18461         stack_trap "exec 4<&-" EXIT
18462
18463         # umount the first lustre mount
18464         umount $MOUNT
18465         stack_trap "mount_client $MOUNT" EXIT
18466
18467         # read changelog, which may or may not fail, but should not crash
18468         cat <&4 >/dev/null
18469
18470         # clear changelog
18471         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18472         changelog_users $SINGLEMDS | grep -q $cl_user ||
18473                 error "User $cl_user not found in changelog_users"
18474
18475         printf 'clear:'$cl_user':0' >&3
18476 }
18477 run_test 160j "client can be umounted while its chanangelog is being used"
18478
18479 test_160k() {
18480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18481         remote_mds_nodsh && skip "remote MDS with nodsh"
18482
18483         mkdir -p $DIR/$tdir/1/1
18484
18485         changelog_register || error "changelog_register failed"
18486         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18487
18488         changelog_users $SINGLEMDS | grep -q $cl_user ||
18489                 error "User '$cl_user' not found in changelog_users"
18490 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18491         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18492         rmdir $DIR/$tdir/1/1 & sleep 1
18493         mkdir $DIR/$tdir/2
18494         touch $DIR/$tdir/2/2
18495         rm -rf $DIR/$tdir/2
18496
18497         wait
18498         sleep 4
18499
18500         changelog_dump | grep rmdir || error "rmdir not recorded"
18501 }
18502 run_test 160k "Verify that changelog records are not lost"
18503
18504 # Verifies that a file passed as a parameter has recently had an operation
18505 # performed on it that has generated an MTIME changelog which contains the
18506 # correct parent FID. As files might reside on a different MDT from the
18507 # parent directory in DNE configurations, the FIDs are translated to paths
18508 # before being compared, which should be identical
18509 compare_mtime_changelog() {
18510         local file="${1}"
18511         local mdtidx
18512         local mtime
18513         local cl_fid
18514         local pdir
18515         local dir
18516
18517         mdtidx=$($LFS getstripe --mdt-index $file)
18518         mdtidx=$(printf "%04x" $mdtidx)
18519
18520         # Obtain the parent FID from the MTIME changelog
18521         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18522         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18523
18524         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18525         [ -z "$cl_fid" ] && error "parent FID not present"
18526
18527         # Verify that the path for the parent FID is the same as the path for
18528         # the test directory
18529         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18530
18531         dir=$(dirname $1)
18532
18533         [[ "${pdir%/}" == "$dir" ]] ||
18534                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18535 }
18536
18537 test_160l() {
18538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18539
18540         remote_mds_nodsh && skip "remote MDS with nodsh"
18541         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18542                 skip "Need MDS version at least 2.13.55"
18543
18544         local cl_user
18545
18546         changelog_register || error "changelog_register failed"
18547         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18548
18549         changelog_users $SINGLEMDS | grep -q $cl_user ||
18550                 error "User '$cl_user' not found in changelog_users"
18551
18552         # Clear some types so that MTIME changelogs are generated
18553         changelog_chmask "-CREAT"
18554         changelog_chmask "-CLOSE"
18555
18556         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18557
18558         # Test CL_MTIME during setattr
18559         touch $DIR/$tdir/$tfile
18560         compare_mtime_changelog $DIR/$tdir/$tfile
18561
18562         # Test CL_MTIME during close
18563         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18564         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18565 }
18566 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18567
18568 test_160m() {
18569         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18570         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18571                 skip "Need MDS version at least 2.14.51"
18572         local cl_users
18573         local cl_user1
18574         local cl_user2
18575         local pid1
18576
18577         # Create a user
18578         changelog_register || error "first changelog_register failed"
18579         changelog_register || error "second changelog_register failed"
18580
18581         cl_users=(${CL_USERS[mds1]})
18582         cl_user1="${cl_users[0]}"
18583         cl_user2="${cl_users[1]}"
18584         # generate some changelog records to accumulate on MDT0
18585         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18586         createmany -m $DIR/$tdir/$tfile 50 ||
18587                 error "create $DIR/$tdir/$tfile failed"
18588         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18589         rm -f $DIR/$tdir
18590
18591         # check changelogs have been generated
18592         local nbcl=$(changelog_dump | wc -l)
18593         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18594
18595 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18596         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18597
18598         __changelog_clear mds1 $cl_user1 +10
18599         __changelog_clear mds1 $cl_user2 0 &
18600         pid1=$!
18601         sleep 2
18602         __changelog_clear mds1 $cl_user1 0 ||
18603                 error "fail to cancel record for $cl_user1"
18604         wait $pid1
18605         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18606 }
18607 run_test 160m "Changelog clear race"
18608
18609 test_160n() {
18610         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18611         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18612                 skip "Need MDS version at least 2.14.51"
18613         local cl_users
18614         local cl_user1
18615         local cl_user2
18616         local pid1
18617         local first_rec
18618         local last_rec=0
18619
18620         # Create a user
18621         changelog_register || error "first changelog_register failed"
18622
18623         cl_users=(${CL_USERS[mds1]})
18624         cl_user1="${cl_users[0]}"
18625
18626         # generate some changelog records to accumulate on MDT0
18627         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18628         first_rec=$(changelog_users $SINGLEMDS |
18629                         awk '/^current.index:/ { print $NF }')
18630         while (( last_rec < (( first_rec + 65000)) )); do
18631                 createmany -m $DIR/$tdir/$tfile 10000 ||
18632                         error "create $DIR/$tdir/$tfile failed"
18633
18634                 for i in $(seq 0 10000); do
18635                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18636                                 > /dev/null
18637                 done
18638
18639                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18640                         error "unlinkmany failed unlink"
18641                 last_rec=$(changelog_users $SINGLEMDS |
18642                         awk '/^current.index:/ { print $NF }')
18643                 echo last record $last_rec
18644                 (( last_rec == 0 )) && error "no changelog found"
18645         done
18646
18647 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18648         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18649
18650         __changelog_clear mds1 $cl_user1 0 &
18651         pid1=$!
18652         sleep 2
18653         __changelog_clear mds1 $cl_user1 0 ||
18654                 error "fail to cancel record for $cl_user1"
18655         wait $pid1
18656         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18657 }
18658 run_test 160n "Changelog destroy race"
18659
18660 test_160o() {
18661         local mdt="$(facet_svc $SINGLEMDS)"
18662
18663         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18664         remote_mds_nodsh && skip "remote MDS with nodsh"
18665         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18666                 skip "Need MDS version at least 2.14.52"
18667
18668         changelog_register --user test_160o -m unlnk+close+open ||
18669                 error "changelog_register failed"
18670
18671         do_facet $SINGLEMDS $LCTL --device $mdt \
18672                                 changelog_register -u "Tt3_-#" &&
18673                 error "bad symbols in name should fail"
18674
18675         do_facet $SINGLEMDS $LCTL --device $mdt \
18676                                 changelog_register -u test_160o &&
18677                 error "the same name registration should fail"
18678
18679         do_facet $SINGLEMDS $LCTL --device $mdt \
18680                         changelog_register -u test_160toolongname &&
18681                 error "too long name registration should fail"
18682
18683         changelog_chmask "MARK+HSM"
18684         lctl get_param mdd.*.changelog*mask
18685         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18686         changelog_users $SINGLEMDS | grep -q $cl_user ||
18687                 error "User $cl_user not found in changelog_users"
18688         #verify username
18689         echo $cl_user | grep -q test_160o ||
18690                 error "User $cl_user has no specific name 'test160o'"
18691
18692         # change something
18693         changelog_clear 0 || error "changelog_clear failed"
18694         # generate some changelog records to accumulate on MDT0
18695         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18696         touch $DIR/$tdir/$tfile                 # open 1
18697
18698         OPENS=$(changelog_dump | grep -c "OPEN")
18699         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18700
18701         # must be no MKDIR it wasn't set as user mask
18702         MKDIR=$(changelog_dump | grep -c "MKDIR")
18703         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18704
18705         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18706                                 mdd.$mdt.changelog_current_mask -n)
18707         # register maskless user
18708         changelog_register || error "changelog_register failed"
18709         # effective mask should be not changed because it is not minimal
18710         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18711                                 mdd.$mdt.changelog_current_mask -n)
18712         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18713         # set server mask to minimal value
18714         changelog_chmask "MARK"
18715         # check effective mask again, should be treated as DEFMASK now
18716         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18717                                 mdd.$mdt.changelog_current_mask -n)
18718         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18719
18720         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18721                 # set server mask back to some value
18722                 changelog_chmask "CLOSE,UNLNK"
18723                 # check effective mask again, should not remain as DEFMASK
18724                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18725                                 mdd.$mdt.changelog_current_mask -n)
18726                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18727         fi
18728
18729         do_facet $SINGLEMDS $LCTL --device $mdt \
18730                                 changelog_deregister -u test_160o ||
18731                 error "cannot deregister by name"
18732 }
18733 run_test 160o "changelog user name and mask"
18734
18735 test_160p() {
18736         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18737         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18738                 skip "Need MDS version at least 2.14.51"
18739         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18740         local cl_users
18741         local cl_user1
18742         local entry_count
18743
18744         # Create a user
18745         changelog_register || error "first changelog_register failed"
18746
18747         cl_users=(${CL_USERS[mds1]})
18748         cl_user1="${cl_users[0]}"
18749
18750         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18751         createmany -m $DIR/$tdir/$tfile 50 ||
18752                 error "create $DIR/$tdir/$tfile failed"
18753         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18754         rm -rf $DIR/$tdir
18755
18756         # check changelogs have been generated
18757         entry_count=$(changelog_dump | wc -l)
18758         ((entry_count != 0)) || error "no changelog entries found"
18759
18760         # remove changelog_users and check that orphan entries are removed
18761         stop mds1
18762         local dev=$(mdsdevname 1)
18763         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18764         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18765         entry_count=$(changelog_dump | wc -l)
18766         ((entry_count == 0)) ||
18767                 error "found $entry_count changelog entries, expected none"
18768 }
18769 run_test 160p "Changelog orphan cleanup with no users"
18770
18771 test_160q() {
18772         local mdt="$(facet_svc $SINGLEMDS)"
18773         local clu
18774
18775         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18776         remote_mds_nodsh && skip "remote MDS with nodsh"
18777         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18778                 skip "Need MDS version at least 2.14.54"
18779
18780         # set server mask to minimal value like server init does
18781         changelog_chmask "MARK"
18782         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18783                 error "changelog_register failed"
18784         # check effective mask again, should be treated as DEFMASK now
18785         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18786                                 mdd.$mdt.changelog_current_mask -n)
18787         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18788                 error "changelog_deregister failed"
18789         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18790 }
18791 run_test 160q "changelog effective mask is DEFMASK if not set"
18792
18793 test_160s() {
18794         remote_mds_nodsh && skip "remote MDS with nodsh"
18795         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18796                 skip "Need MDS version at least 2.14.55"
18797
18798         local mdts=$(comma_list $(mdts_nodes))
18799
18800         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18801         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18802                                        fail_val=$((24 * 3600 * 10))
18803
18804         # Create a user which is 10 days old
18805         changelog_register || error "first changelog_register failed"
18806         local cl_users
18807         declare -A cl_user1
18808         local i
18809
18810         # generate some changelog records to accumulate on each MDT
18811         # use all_char because created files should be evenly distributed
18812         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18813                 error "test_mkdir $tdir failed"
18814         for ((i = 0; i < MDSCOUNT; i++)); do
18815                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18816                         error "create $DIR/$tdir/d$i.1 failed"
18817         done
18818
18819         # check changelogs have been generated
18820         local nbcl=$(changelog_dump | wc -l)
18821         (( nbcl > 0 )) || error "no changelogs found"
18822
18823         # reduce the max_idle_indexes value to make sure we exceed it
18824         for param in "changelog_max_idle_indexes=2097446912" \
18825                      "changelog_max_idle_time=2592000" \
18826                      "changelog_gc=1" \
18827                      "changelog_min_gc_interval=2"; do
18828                 local MDT0=$(facet_svc $SINGLEMDS)
18829                 local var="${param%=*}"
18830                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18831
18832                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18833                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18834                         error "unable to set mdd.*.$param"
18835         done
18836
18837         local start=$SECONDS
18838         for i in $(seq $MDSCOUNT); do
18839                 cl_users=(${CL_USERS[mds$i]})
18840                 cl_user1[mds$i]="${cl_users[0]}"
18841
18842                 [[ -n "${cl_user1[mds$i]}" ]] ||
18843                         error "mds$i: no user registered"
18844         done
18845
18846         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18847         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18848
18849         # ensure we are past the previous changelog_min_gc_interval set above
18850         local sleep2=$((start + 2 - SECONDS))
18851         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18852
18853         # Generate one more changelog to trigger GC
18854         for ((i = 0; i < MDSCOUNT; i++)); do
18855                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18856                         error "create $DIR/$tdir/d$i.3 failed"
18857         done
18858
18859         # ensure gc thread is done
18860         for node in $(mdts_nodes); do
18861                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18862                         error "$node: GC-thread not done"
18863         done
18864
18865         do_nodes $mdts $LCTL set_param fail_loc=0
18866
18867         for (( i = 1; i <= MDSCOUNT; i++ )); do
18868                 # check cl_user1 is purged
18869                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18870                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18871         done
18872         return 0
18873 }
18874 run_test 160s "changelog garbage collect on idle records * time"
18875
18876 test_160t() {
18877         remote_mds_nodsh && skip "remote MDS with nodsh"
18878         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18879                 skip "Need MDS version at least 2.15.50"
18880
18881         local MDT0=$(facet_svc $SINGLEMDS)
18882         local cl_users
18883         local cl_user1
18884         local cl_user2
18885         local start
18886
18887         changelog_register --user user1 -m all ||
18888                 error "user1 failed to register"
18889
18890         mkdir_on_mdt0 $DIR/$tdir
18891         # create default overstripe to maximize changelog size
18892         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18893         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18894         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18895
18896         # user2 consumes less records so less space
18897         changelog_register --user user2 || error "user2 failed to register"
18898         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18899         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18900
18901         # check changelogs have been generated
18902         local nbcl=$(changelog_dump | wc -l)
18903         (( nbcl > 0 )) || error "no changelogs found"
18904
18905         # reduce the changelog_min_gc_interval to force check
18906         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18907                 local var="${param%=*}"
18908                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18909
18910                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18911                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18912                         error "unable to set mdd.*.$param"
18913         done
18914
18915         start=$SECONDS
18916         cl_users=(${CL_USERS[mds1]})
18917         cl_user1="${cl_users[0]}"
18918         cl_user2="${cl_users[1]}"
18919
18920         [[ -n $cl_user1 ]] ||
18921                 error "mds1: user #1 isn't registered"
18922         [[ -n $cl_user2 ]] ||
18923                 error "mds1: user #2 isn't registered"
18924
18925         # ensure we are past the previous changelog_min_gc_interval set above
18926         local sleep2=$((start + 2 - SECONDS))
18927         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18928
18929         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18930         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18931                         fail_val=$(((llog_size1 + llog_size2) / 2))
18932
18933         # Generate more changelog to trigger GC
18934         createmany -o $DIR/$tdir/u3_ 4 ||
18935                 error "create failed for more files"
18936
18937         # ensure gc thread is done
18938         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18939                 error "mds1: GC-thread not done"
18940
18941         do_facet mds1 $LCTL set_param fail_loc=0
18942
18943         # check cl_user1 is purged
18944         changelog_users mds1 | grep -q "$cl_user1" &&
18945                 error "User $cl_user1 is registered"
18946         # check cl_user2 is not purged
18947         changelog_users mds1 | grep -q "$cl_user2" ||
18948                 error "User $cl_user2 is not registered"
18949 }
18950 run_test 160t "changelog garbage collect on lack of space"
18951
18952 test_160u() { # LU-17400
18953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18954         remote_mds_nodsh && skip "remote MDS with nodsh"
18955         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18956                 skip "Need MDS version at least 2.2.0"
18957
18958         cd $DIR || error "cd $DIR failed"
18959
18960         # ensure changelog has a clean view if tests are run multiple times
18961         [ -d rename ] && rm -rf rename
18962
18963         changelog_register || error "changelog_register failed"
18964         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18965
18966         changelog_users $SINGLEMDS | grep -q $cl_user ||
18967                 error "User '$cl_user' not found in changelog_users"
18968
18969         local longname1=$(str_repeat a 255)
18970
18971         echo "creating simple directory tree"
18972         mkdir -p rename/a || error "create of simple directory tree failed"
18973         echo "creating rename/hw file"
18974         echo "hello world" > rename/hw || error "create of rename/hw failed"
18975         echo "creating very long named file"
18976         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18977         echo "move rename/hw to rename/a/a.hw"
18978         mv rename/hw rename/a/a.hw || error "mv failed"
18979
18980         RENME=($(changelog_dump | grep "RENME"))
18981         #declare -p RENME # for debugging captured value with indexes
18982
18983         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18984                 error "changelog rename record type name/sname error"
18985 }
18986 run_test 160u "changelog rename record type name and sname strings are correct"
18987
18988 test_161a() {
18989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18990
18991         test_mkdir -c1 $DIR/$tdir
18992         cp /etc/hosts $DIR/$tdir/$tfile
18993         test_mkdir -c1 $DIR/$tdir/foo1
18994         test_mkdir -c1 $DIR/$tdir/foo2
18995         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18996         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18997         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18998         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18999         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
19000         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19001                 $LFS fid2path $DIR $FID
19002                 error "bad link ea"
19003         fi
19004         # middle
19005         rm $DIR/$tdir/foo2/zachary
19006         # last
19007         rm $DIR/$tdir/foo2/thor
19008         # first
19009         rm $DIR/$tdir/$tfile
19010         # rename
19011         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
19012         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
19013                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
19014         rm $DIR/$tdir/foo2/maggie
19015
19016         # overflow the EA
19017         local longname=$tfile.avg_len_is_thirty_two_
19018         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
19019                 error_noexit 'failed to unlink many hardlinks'" EXIT
19020         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
19021                 error "failed to hardlink many files"
19022         links=$($LFS fid2path $DIR $FID | wc -l)
19023         echo -n "${links}/1000 links in link EA"
19024         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
19025 }
19026 run_test 161a "link ea sanity"
19027
19028 test_161b() {
19029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19030         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
19031
19032         local MDTIDX=1
19033         local remote_dir=$DIR/$tdir/remote_dir
19034
19035         mkdir -p $DIR/$tdir
19036         $LFS mkdir -i $MDTIDX $remote_dir ||
19037                 error "create remote directory failed"
19038
19039         cp /etc/hosts $remote_dir/$tfile
19040         mkdir -p $remote_dir/foo1
19041         mkdir -p $remote_dir/foo2
19042         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19043         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19044         ln $remote_dir/$tfile $remote_dir/foo1/luna
19045         ln $remote_dir/$tfile $remote_dir/foo2/thor
19046
19047         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19048                      tr -d ']')
19049         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19050                 $LFS fid2path $DIR $FID
19051                 error "bad link ea"
19052         fi
19053         # middle
19054         rm $remote_dir/foo2/zachary
19055         # last
19056         rm $remote_dir/foo2/thor
19057         # first
19058         rm $remote_dir/$tfile
19059         # rename
19060         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19061         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19062         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19063                 $LFS fid2path $DIR $FID
19064                 error "bad link rename"
19065         fi
19066         rm $remote_dir/foo2/maggie
19067
19068         # overflow the EA
19069         local longname=filename_avg_len_is_thirty_two_
19070         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19071                 error "failed to hardlink many files"
19072         links=$($LFS fid2path $DIR $FID | wc -l)
19073         echo -n "${links}/1000 links in link EA"
19074         [[ ${links} -gt 60 ]] ||
19075                 error "expected at least 60 links in link EA"
19076         unlinkmany $remote_dir/foo2/$longname 1000 ||
19077         error "failed to unlink many hardlinks"
19078 }
19079 run_test 161b "link ea sanity under remote directory"
19080
19081 test_161c() {
19082         remote_mds_nodsh && skip "remote MDS with nodsh"
19083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19084         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19085                 skip "Need MDS version at least 2.1.5"
19086
19087         # define CLF_RENAME_LAST 0x0001
19088         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19089         changelog_register || error "changelog_register failed"
19090
19091         rm -rf $DIR/$tdir
19092         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19093         touch $DIR/$tdir/foo_161c
19094         touch $DIR/$tdir/bar_161c
19095         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19096         changelog_dump | grep RENME | tail -n 5
19097         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19098         changelog_clear 0 || error "changelog_clear failed"
19099         if [ x$flags != "x0x1" ]; then
19100                 error "flag $flags is not 0x1"
19101         fi
19102
19103         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19104         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19105         touch $DIR/$tdir/foo_161c
19106         touch $DIR/$tdir/bar_161c
19107         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19108         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19109         changelog_dump | grep RENME | tail -n 5
19110         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19111         changelog_clear 0 || error "changelog_clear failed"
19112         if [ x$flags != "x0x0" ]; then
19113                 error "flag $flags is not 0x0"
19114         fi
19115         echo "rename overwrite a target having nlink > 1," \
19116                 "changelog record has flags of $flags"
19117
19118         # rename doesn't overwrite a target (changelog flag 0x0)
19119         touch $DIR/$tdir/foo_161c
19120         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19121         changelog_dump | grep RENME | tail -n 5
19122         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19123         changelog_clear 0 || error "changelog_clear failed"
19124         if [ x$flags != "x0x0" ]; then
19125                 error "flag $flags is not 0x0"
19126         fi
19127         echo "rename doesn't overwrite a target," \
19128                 "changelog record has flags of $flags"
19129
19130         # define CLF_UNLINK_LAST 0x0001
19131         # unlink a file having nlink = 1 (changelog flag 0x1)
19132         rm -f $DIR/$tdir/foo2_161c
19133         changelog_dump | grep UNLNK | tail -n 5
19134         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19135         changelog_clear 0 || error "changelog_clear failed"
19136         if [ x$flags != "x0x1" ]; then
19137                 error "flag $flags is not 0x1"
19138         fi
19139         echo "unlink a file having nlink = 1," \
19140                 "changelog record has flags of $flags"
19141
19142         # unlink a file having nlink > 1 (changelog flag 0x0)
19143         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19144         rm -f $DIR/$tdir/foobar_161c
19145         changelog_dump | grep UNLNK | tail -n 5
19146         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19147         changelog_clear 0 || error "changelog_clear failed"
19148         if [ x$flags != "x0x0" ]; then
19149                 error "flag $flags is not 0x0"
19150         fi
19151         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19152 }
19153 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19154
19155 test_161d() {
19156         remote_mds_nodsh && skip "remote MDS with nodsh"
19157         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19158
19159         local pid
19160         local fid
19161
19162         changelog_register || error "changelog_register failed"
19163
19164         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19165         # interfer with $MOUNT/.lustre/fid/ access
19166         mkdir $DIR/$tdir
19167         [[ $? -eq 0 ]] || error "mkdir failed"
19168
19169         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19170         $LCTL set_param fail_loc=0x8000140c
19171         # 5s pause
19172         $LCTL set_param fail_val=5
19173
19174         # create file
19175         echo foofoo > $DIR/$tdir/$tfile &
19176         pid=$!
19177
19178         # wait for create to be delayed
19179         sleep 2
19180
19181         ps -p $pid
19182         [[ $? -eq 0 ]] || error "create should be blocked"
19183
19184         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19185         stack_trap "rm -f $tempfile"
19186         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19187         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19188         # some delay may occur during ChangeLog publishing and file read just
19189         # above, that could allow file write to happen finally
19190         [[ -s $tempfile ]] && echo "file should be empty"
19191
19192         $LCTL set_param fail_loc=0
19193
19194         wait $pid
19195         [[ $? -eq 0 ]] || error "create failed"
19196 }
19197 run_test 161d "create with concurrent .lustre/fid access"
19198
19199 check_path() {
19200         local expected="$1"
19201         shift
19202         local fid="$2"
19203
19204         local path
19205         path=$($LFS fid2path "$@")
19206         local rc=$?
19207
19208         if [ $rc -ne 0 ]; then
19209                 error "path looked up of '$expected' failed: rc=$rc"
19210         elif [ "$path" != "$expected" ]; then
19211                 error "path looked up '$path' instead of '$expected'"
19212         else
19213                 echo "FID '$fid' resolves to path '$path' as expected"
19214         fi
19215 }
19216
19217 test_162a() { # was test_162
19218         test_mkdir -p -c1 $DIR/$tdir/d2
19219         touch $DIR/$tdir/d2/$tfile
19220         touch $DIR/$tdir/d2/x1
19221         touch $DIR/$tdir/d2/x2
19222         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19223         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19224         # regular file
19225         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19226         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19227
19228         # softlink
19229         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19230         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19231         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19232
19233         # softlink to wrong file
19234         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19235         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19236         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19237
19238         # hardlink
19239         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19240         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19241         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19242         # fid2path dir/fsname should both work
19243         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19244         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19245
19246         # hardlink count: check that there are 2 links
19247         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19248         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19249
19250         # hardlink indexing: remove the first link
19251         rm $DIR/$tdir/d2/p/q/r/hlink
19252         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19253 }
19254 run_test 162a "path lookup sanity"
19255
19256 test_162b() {
19257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19258         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19259
19260         mkdir $DIR/$tdir
19261         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19262                                 error "create striped dir failed"
19263
19264         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19265                                         tail -n 1 | awk '{print $2}')
19266         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19267
19268         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19269         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19270
19271         # regular file
19272         for ((i=0;i<5;i++)); do
19273                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19274                         error "get fid for f$i failed"
19275                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19276
19277                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19278                         error "get fid for d$i failed"
19279                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19280         done
19281
19282         return 0
19283 }
19284 run_test 162b "striped directory path lookup sanity"
19285
19286 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19287 test_162c() {
19288         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19289                 skip "Need MDS version at least 2.7.51"
19290
19291         local lpath=$tdir.local
19292         local rpath=$tdir.remote
19293
19294         test_mkdir $DIR/$lpath
19295         test_mkdir $DIR/$rpath
19296
19297         for ((i = 0; i <= 101; i++)); do
19298                 lpath="$lpath/$i"
19299                 mkdir $DIR/$lpath
19300                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19301                         error "get fid for local directory $DIR/$lpath failed"
19302                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19303
19304                 rpath="$rpath/$i"
19305                 test_mkdir $DIR/$rpath
19306                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19307                         error "get fid for remote directory $DIR/$rpath failed"
19308                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19309         done
19310
19311         return 0
19312 }
19313 run_test 162c "fid2path works with paths 100 or more directories deep"
19314
19315 oalr_event_count() {
19316         local event="${1}"
19317         local trace="${2}"
19318
19319         awk -v name="${FSNAME}-OST0000" \
19320             -v event="${event}" \
19321             '$1 == "TRACE" && $2 == event && $3 == name' \
19322             "${trace}" |
19323         wc -l
19324 }
19325
19326 oalr_expect_event_count() {
19327         local event="${1}"
19328         local trace="${2}"
19329         local expect="${3}"
19330         local count
19331
19332         count=$(oalr_event_count "${event}" "${trace}")
19333         if ((count == expect)); then
19334                 return 0
19335         fi
19336
19337         error_noexit "${event} event count was '${count}', expected ${expect}"
19338         cat "${trace}" >&2
19339         exit 1
19340 }
19341
19342 cleanup_165() {
19343         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19344         stop ost1
19345         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19346 }
19347
19348 setup_165() {
19349         sync # Flush previous IOs so we can count log entries.
19350         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19351         stack_trap cleanup_165 EXIT
19352 }
19353
19354 test_165a() {
19355         local trace="/tmp/${tfile}.trace"
19356         local rc
19357         local count
19358
19359         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19360                 skip "OFD access log unsupported"
19361
19362         setup_165
19363         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19364         sleep 5
19365
19366         do_facet ost1 ofd_access_log_reader --list
19367         stop ost1
19368
19369         do_facet ost1 killall -TERM ofd_access_log_reader
19370         wait
19371         rc=$?
19372
19373         if ((rc != 0)); then
19374                 error "ofd_access_log_reader exited with rc = '${rc}'"
19375         fi
19376
19377         # Parse trace file for discovery events:
19378         oalr_expect_event_count alr_log_add "${trace}" 1
19379         oalr_expect_event_count alr_log_eof "${trace}" 1
19380         oalr_expect_event_count alr_log_free "${trace}" 1
19381 }
19382 run_test 165a "ofd access log discovery"
19383
19384 test_165b() {
19385         local trace="/tmp/${tfile}.trace"
19386         local file="${DIR}/${tfile}"
19387         local pfid1
19388         local pfid2
19389         local -a entry
19390         local rc
19391         local count
19392         local size
19393         local flags
19394
19395         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19396                 skip "OFD access log unsupported"
19397
19398         setup_165
19399         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19400         sleep 5
19401
19402         do_facet ost1 ofd_access_log_reader --list
19403
19404         lfs setstripe -c 1 -i 0 "${file}"
19405         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19406                 error "cannot create '${file}'"
19407
19408         sleep 5
19409         do_facet ost1 killall -TERM ofd_access_log_reader
19410         wait
19411         rc=$?
19412
19413         if ((rc != 0)); then
19414                 error "ofd_access_log_reader exited with rc = '${rc}'"
19415         fi
19416
19417         oalr_expect_event_count alr_log_entry "${trace}" 1
19418
19419         pfid1=$($LFS path2fid "${file}")
19420
19421         # 1     2             3   4    5     6   7    8    9     10
19422         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19423         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19424
19425         echo "entry = '${entry[*]}'" >&2
19426
19427         pfid2=${entry[4]}
19428         if [[ "${pfid1}" != "${pfid2}" ]]; then
19429                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19430         fi
19431
19432         size=${entry[8]}
19433         if ((size != 1048576)); then
19434                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19435         fi
19436
19437         flags=${entry[10]}
19438         if [[ "${flags}" != "w" ]]; then
19439                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19440         fi
19441
19442         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19443         sleep 5
19444
19445         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19446                 error "cannot read '${file}'"
19447         sleep 5
19448
19449         do_facet ost1 killall -TERM ofd_access_log_reader
19450         wait
19451         rc=$?
19452
19453         if ((rc != 0)); then
19454                 error "ofd_access_log_reader exited with rc = '${rc}'"
19455         fi
19456
19457         oalr_expect_event_count alr_log_entry "${trace}" 1
19458
19459         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19460         echo "entry = '${entry[*]}'" >&2
19461
19462         pfid2=${entry[4]}
19463         if [[ "${pfid1}" != "${pfid2}" ]]; then
19464                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19465         fi
19466
19467         size=${entry[8]}
19468         if ((size != 524288)); then
19469                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19470         fi
19471
19472         flags=${entry[10]}
19473         if [[ "${flags}" != "r" ]]; then
19474                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19475         fi
19476 }
19477 run_test 165b "ofd access log entries are produced and consumed"
19478
19479 test_165c() {
19480         local trace="/tmp/${tfile}.trace"
19481         local file="${DIR}/${tdir}/${tfile}"
19482
19483         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19484                 skip "OFD access log unsupported"
19485
19486         test_mkdir "${DIR}/${tdir}"
19487
19488         setup_165
19489         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19490         sleep 5
19491
19492         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19493
19494         # 4096 / 64 = 64. Create twice as many entries.
19495         for ((i = 0; i < 128; i++)); do
19496                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19497                         error "cannot create file"
19498         done
19499
19500         sync
19501
19502         do_facet ost1 killall -TERM ofd_access_log_reader
19503         wait
19504         rc=$?
19505         if ((rc != 0)); then
19506                 error "ofd_access_log_reader exited with rc = '${rc}'"
19507         fi
19508
19509         unlinkmany  "${file}-%d" 128
19510 }
19511 run_test 165c "full ofd access logs do not block IOs"
19512
19513 oal_get_read_count() {
19514         local stats="$1"
19515
19516         # STATS lustre-OST0001 alr_read_count 1
19517
19518         do_facet ost1 cat "${stats}" |
19519         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19520              END { print count; }'
19521 }
19522
19523 oal_expect_read_count() {
19524         local stats="$1"
19525         local count
19526         local expect="$2"
19527
19528         # Ask ofd_access_log_reader to write stats.
19529         do_facet ost1 killall -USR1 ofd_access_log_reader
19530
19531         # Allow some time for things to happen.
19532         sleep 1
19533
19534         count=$(oal_get_read_count "${stats}")
19535         if ((count == expect)); then
19536                 return 0
19537         fi
19538
19539         error_noexit "bad read count, got ${count}, expected ${expect}"
19540         do_facet ost1 cat "${stats}" >&2
19541         exit 1
19542 }
19543
19544 test_165d() {
19545         local stats="/tmp/${tfile}.stats"
19546         local file="${DIR}/${tdir}/${tfile}"
19547         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19548
19549         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19550                 skip "OFD access log unsupported"
19551
19552         test_mkdir "${DIR}/${tdir}"
19553
19554         setup_165
19555         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19556         sleep 5
19557
19558         lfs setstripe -c 1 -i 0 "${file}"
19559
19560         do_facet ost1 lctl set_param "${param}=rw"
19561         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19562                 error "cannot create '${file}'"
19563         oal_expect_read_count "${stats}" 1
19564
19565         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19566                 error "cannot read '${file}'"
19567         oal_expect_read_count "${stats}" 2
19568
19569         do_facet ost1 lctl set_param "${param}=r"
19570         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19571                 error "cannot create '${file}'"
19572         oal_expect_read_count "${stats}" 2
19573
19574         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19575                 error "cannot read '${file}'"
19576         oal_expect_read_count "${stats}" 3
19577
19578         do_facet ost1 lctl set_param "${param}=w"
19579         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19580                 error "cannot create '${file}'"
19581         oal_expect_read_count "${stats}" 4
19582
19583         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19584                 error "cannot read '${file}'"
19585         oal_expect_read_count "${stats}" 4
19586
19587         do_facet ost1 lctl set_param "${param}=0"
19588         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19589                 error "cannot create '${file}'"
19590         oal_expect_read_count "${stats}" 4
19591
19592         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19593                 error "cannot read '${file}'"
19594         oal_expect_read_count "${stats}" 4
19595
19596         do_facet ost1 killall -TERM ofd_access_log_reader
19597         wait
19598         rc=$?
19599         if ((rc != 0)); then
19600                 error "ofd_access_log_reader exited with rc = '${rc}'"
19601         fi
19602 }
19603 run_test 165d "ofd_access_log mask works"
19604
19605 test_165e() {
19606         local stats="/tmp/${tfile}.stats"
19607         local file0="${DIR}/${tdir}-0/${tfile}"
19608         local file1="${DIR}/${tdir}-1/${tfile}"
19609
19610         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19611                 skip "OFD access log unsupported"
19612
19613         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19614
19615         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19616         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19617
19618         lfs setstripe -c 1 -i 0 "${file0}"
19619         lfs setstripe -c 1 -i 0 "${file1}"
19620
19621         setup_165
19622         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19623         sleep 5
19624
19625         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19626                 error "cannot create '${file0}'"
19627         sync
19628         oal_expect_read_count "${stats}" 0
19629
19630         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19631                 error "cannot create '${file1}'"
19632         sync
19633         oal_expect_read_count "${stats}" 1
19634
19635         do_facet ost1 killall -TERM ofd_access_log_reader
19636         wait
19637         rc=$?
19638         if ((rc != 0)); then
19639                 error "ofd_access_log_reader exited with rc = '${rc}'"
19640         fi
19641 }
19642 run_test 165e "ofd_access_log MDT index filter works"
19643
19644 test_165f() {
19645         local trace="/tmp/${tfile}.trace"
19646         local rc
19647         local count
19648
19649         setup_165
19650         do_facet ost1 timeout 60 ofd_access_log_reader \
19651                 --exit-on-close --debug=- --trace=- > "${trace}" &
19652         sleep 5
19653         stop ost1
19654
19655         wait
19656         rc=$?
19657
19658         if ((rc != 0)); then
19659                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19660                 cat "${trace}"
19661                 exit 1
19662         fi
19663 }
19664 run_test 165f "ofd_access_log_reader --exit-on-close works"
19665
19666 test_169() {
19667         # do directio so as not to populate the page cache
19668         log "creating a 10 Mb file"
19669         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19670                 error "multiop failed while creating a file"
19671         log "starting reads"
19672         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19673         log "truncating the file"
19674         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19675                 error "multiop failed while truncating the file"
19676         log "killing dd"
19677         kill %+ || true # reads might have finished
19678         echo "wait until dd is finished"
19679         wait
19680         log "removing the temporary file"
19681         rm -rf $DIR/$tfile || error "tmp file removal failed"
19682 }
19683 run_test 169 "parallel read and truncate should not deadlock"
19684
19685 test_170() {
19686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19687
19688         $LCTL clear     # bug 18514
19689         $LCTL debug_daemon start $TMP/${tfile}_log_good
19690         touch $DIR/$tfile
19691         $LCTL debug_daemon stop
19692         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19693                 error "sed failed to read log_good"
19694
19695         $LCTL debug_daemon start $TMP/${tfile}_log_good
19696         rm -rf $DIR/$tfile
19697         $LCTL debug_daemon stop
19698
19699         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19700                error "lctl df log_bad failed"
19701
19702         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19703         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19704
19705         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19706         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19707
19708         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19709                 error "bad_line good_line1 good_line2 are empty"
19710
19711         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19712         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19713         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19714
19715         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19716         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19717         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19718
19719         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19720                 error "bad_line_new good_line_new are empty"
19721
19722         local expected_good=$((good_line1 + good_line2*2))
19723
19724         rm -f $TMP/${tfile}*
19725         # LU-231, short malformed line may not be counted into bad lines
19726         if [ $bad_line -ne $bad_line_new ] &&
19727                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19728                 error "expected $bad_line bad lines, but got $bad_line_new"
19729                 return 1
19730         fi
19731
19732         if [ $expected_good -ne $good_line_new ]; then
19733                 error "expected $expected_good good lines, but got $good_line_new"
19734                 return 2
19735         fi
19736         true
19737 }
19738 run_test 170 "test lctl df to handle corrupted log ====================="
19739
19740 test_171() { # bug20592
19741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19742
19743         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19744         $LCTL set_param fail_loc=0x50e
19745         $LCTL set_param fail_val=3000
19746         multiop_bg_pause $DIR/$tfile O_s || true
19747         local MULTIPID=$!
19748         kill -USR1 $MULTIPID
19749         # cause log dump
19750         sleep 3
19751         wait $MULTIPID
19752         if dmesg | grep "recursive fault"; then
19753                 error "caught a recursive fault"
19754         fi
19755         $LCTL set_param fail_loc=0
19756         true
19757 }
19758 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19759
19760 test_172() {
19761
19762         #define OBD_FAIL_OBD_CLEANUP  0x60e
19763         $LCTL set_param fail_loc=0x60e
19764         umount $MOUNT || error "umount $MOUNT failed"
19765         stack_trap "mount_client $MOUNT"
19766
19767         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19768                 error "no client OBDs are remained"
19769
19770         $LCTL dl | while read devno state type name foo; do
19771                 case $type in
19772                 lov|osc|lmv|mdc)
19773                         $LCTL --device $name cleanup
19774                         $LCTL --device $name detach
19775                         ;;
19776                 *)
19777                         # skip server devices
19778                         ;;
19779                 esac
19780         done
19781
19782         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19783                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19784                 error "some client OBDs are still remained"
19785         fi
19786
19787 }
19788 run_test 172 "manual device removal with lctl cleanup/detach ======"
19789
19790 # it would be good to share it with obdfilter-survey/iokit-libecho code
19791 setup_obdecho_osc () {
19792         local rc=0
19793         local ost_nid=$1
19794         local obdfilter_name=$2
19795         echo "Creating new osc for $obdfilter_name on $ost_nid"
19796         # make sure we can find loopback nid
19797         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19798
19799         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19800                            ${obdfilter_name}_osc_UUID || rc=2; }
19801         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19802                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19803         return $rc
19804 }
19805
19806 cleanup_obdecho_osc () {
19807         local obdfilter_name=$1
19808         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19809         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19810         return 0
19811 }
19812
19813 obdecho_test() {
19814         local OBD=$1
19815         local node=$2
19816         local pages=${3:-64}
19817         local rc=0
19818         local id
19819
19820         local count=10
19821         local obd_size=$(get_obd_size $node $OBD)
19822         local page_size=$(get_page_size $node)
19823         if [[ -n "$obd_size" ]]; then
19824                 local new_count=$((obd_size / (pages * page_size / 1024)))
19825                 [[ $new_count -ge $count ]] || count=$new_count
19826         fi
19827
19828         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19829         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19830                            rc=2; }
19831         if [ $rc -eq 0 ]; then
19832             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19833             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19834         fi
19835         echo "New object id is $id"
19836         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19837                            rc=4; }
19838         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19839                            "test_brw $count w v $pages $id" || rc=4; }
19840         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19841                            rc=4; }
19842         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19843                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19844         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19845                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19846         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19847         return $rc
19848 }
19849
19850 test_180a() {
19851         skip "obdecho on osc is no longer supported"
19852 }
19853 run_test 180a "test obdecho on osc"
19854
19855 test_180b() {
19856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19857         remote_ost_nodsh && skip "remote OST with nodsh"
19858
19859         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19860                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19861                 error "failed to load module obdecho"
19862
19863         local target=$(do_facet ost1 $LCTL dl |
19864                        awk '/obdfilter/ { print $4; exit; }')
19865
19866         if [ -n "$target" ]; then
19867                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19868         else
19869                 do_facet ost1 $LCTL dl
19870                 error "there is no obdfilter target on ost1"
19871         fi
19872 }
19873 run_test 180b "test obdecho directly on obdfilter"
19874
19875 test_180c() { # LU-2598
19876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19877         remote_ost_nodsh && skip "remote OST with nodsh"
19878         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19879                 skip "Need MDS version at least 2.4.0"
19880
19881         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19882                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19883                 error "failed to load module obdecho"
19884
19885         local target=$(do_facet ost1 $LCTL dl |
19886                        awk '/obdfilter/ { print $4; exit; }')
19887
19888         if [ -n "$target" ]; then
19889                 local pages=16384 # 64MB bulk I/O RPC size
19890
19891                 obdecho_test "$target" ost1 "$pages" ||
19892                         error "obdecho_test with pages=$pages failed with $?"
19893         else
19894                 do_facet ost1 $LCTL dl
19895                 error "there is no obdfilter target on ost1"
19896         fi
19897 }
19898 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19899
19900 test_181() { # bug 22177
19901         test_mkdir $DIR/$tdir
19902         # create enough files to index the directory
19903         createmany -o $DIR/$tdir/foobar 4000
19904         # print attributes for debug purpose
19905         lsattr -d .
19906         # open dir
19907         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19908         MULTIPID=$!
19909         # remove the files & current working dir
19910         unlinkmany $DIR/$tdir/foobar 4000
19911         rmdir $DIR/$tdir
19912         kill -USR1 $MULTIPID
19913         wait $MULTIPID
19914         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19915         return 0
19916 }
19917 run_test 181 "Test open-unlinked dir ========================"
19918
19919 test_182a() {
19920         local fcount=1000
19921         local tcount=10
19922
19923         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19924
19925         $LCTL set_param mdc.*.rpc_stats=clear
19926
19927         for (( i = 0; i < $tcount; i++ )) ; do
19928                 mkdir $DIR/$tdir/$i
19929         done
19930
19931         for (( i = 0; i < $tcount; i++ )) ; do
19932                 createmany -o $DIR/$tdir/$i/f- $fcount &
19933         done
19934         wait
19935
19936         for (( i = 0; i < $tcount; i++ )) ; do
19937                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19938         done
19939         wait
19940
19941         $LCTL get_param mdc.*.rpc_stats
19942
19943         rm -rf $DIR/$tdir
19944 }
19945 run_test 182a "Test parallel modify metadata operations from mdc"
19946
19947 test_182b() {
19948         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19949         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19950         local dcount=1000
19951         local tcount=10
19952         local stime
19953         local etime
19954         local delta
19955
19956         do_facet mds1 $LCTL list_param \
19957                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19958                 skip "MDS lacks parallel RPC handling"
19959
19960         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19961
19962         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19963                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19964
19965         stime=$(date +%s)
19966         createmany -i 0 -d $DIR/$tdir/t- $tcount
19967
19968         for (( i = 0; i < $tcount; i++ )) ; do
19969                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19970         done
19971         wait
19972         etime=$(date +%s)
19973         delta=$((etime - stime))
19974         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19975
19976         stime=$(date +%s)
19977         for (( i = 0; i < $tcount; i++ )) ; do
19978                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19979         done
19980         wait
19981         etime=$(date +%s)
19982         delta=$((etime - stime))
19983         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19984
19985         rm -rf $DIR/$tdir
19986
19987         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19988
19989         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19990
19991         stime=$(date +%s)
19992         createmany -i 0 -d $DIR/$tdir/t- $tcount
19993
19994         for (( i = 0; i < $tcount; i++ )) ; do
19995                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19996         done
19997         wait
19998         etime=$(date +%s)
19999         delta=$((etime - stime))
20000         echo "Time for file creation $delta sec for 1 RPC sent at a time"
20001
20002         stime=$(date +%s)
20003         for (( i = 0; i < $tcount; i++ )) ; do
20004                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
20005         done
20006         wait
20007         etime=$(date +%s)
20008         delta=$((etime - stime))
20009         echo "Time for file removal $delta sec for 1 RPC sent at a time"
20010
20011         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
20012 }
20013 run_test 182b "Test parallel modify metadata operations from osp"
20014
20015 test_183() { # LU-2275
20016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20017         remote_mds_nodsh && skip "remote MDS with nodsh"
20018         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
20019                 skip "Need MDS version at least 2.3.56"
20020
20021         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
20022         echo aaa > $DIR/$tdir/$tfile
20023
20024 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
20025         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
20026
20027         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
20028         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
20029
20030         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20031
20032         # Flush negative dentry cache
20033         touch $DIR/$tdir/$tfile
20034
20035         # We are not checking for any leaked references here, they'll
20036         # become evident next time we do cleanup with module unload.
20037         rm -rf $DIR/$tdir
20038 }
20039 run_test 183 "No crash or request leak in case of strange dispositions ========"
20040
20041 # test suite 184 is for LU-2016, LU-2017
20042 test_184a() {
20043         check_swap_layouts_support
20044
20045         dir0=$DIR/$tdir/$testnum
20046         test_mkdir -p -c1 $dir0
20047         ref1=/etc/passwd
20048         ref2=/etc/group
20049         file1=$dir0/f1
20050         file2=$dir0/f2
20051         $LFS setstripe -c1 $file1
20052         cp $ref1 $file1
20053         $LFS setstripe -c2 $file2
20054         cp $ref2 $file2
20055         gen1=$($LFS getstripe -g $file1)
20056         gen2=$($LFS getstripe -g $file2)
20057
20058         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20059         gen=$($LFS getstripe -g $file1)
20060         [[ $gen1 != $gen ]] ||
20061                 error "Layout generation on $file1 does not change"
20062         gen=$($LFS getstripe -g $file2)
20063         [[ $gen2 != $gen ]] ||
20064                 error "Layout generation on $file2 does not change"
20065
20066         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20067         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20068
20069         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20070 }
20071 run_test 184a "Basic layout swap"
20072
20073 test_184b() {
20074         check_swap_layouts_support
20075
20076         dir0=$DIR/$tdir/$testnum
20077         mkdir -p $dir0 || error "creating dir $dir0"
20078         file1=$dir0/f1
20079         file2=$dir0/f2
20080         file3=$dir0/f3
20081         dir1=$dir0/d1
20082         dir2=$dir0/d2
20083         mkdir $dir1 $dir2
20084         $LFS setstripe -c1 $file1
20085         $LFS setstripe -c2 $file2
20086         $LFS setstripe -c1 $file3
20087         chown $RUNAS_ID $file3
20088         gen1=$($LFS getstripe -g $file1)
20089         gen2=$($LFS getstripe -g $file2)
20090
20091         $LFS swap_layouts $dir1 $dir2 &&
20092                 error "swap of directories layouts should fail"
20093         $LFS swap_layouts $dir1 $file1 &&
20094                 error "swap of directory and file layouts should fail"
20095         $RUNAS $LFS swap_layouts $file1 $file2 &&
20096                 error "swap of file we cannot write should fail"
20097         $LFS swap_layouts $file1 $file3 &&
20098                 error "swap of file with different owner should fail"
20099         /bin/true # to clear error code
20100 }
20101 run_test 184b "Forbidden layout swap (will generate errors)"
20102
20103 test_184c() {
20104         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20105         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20106         check_swap_layouts_support
20107         check_swap_layout_no_dom $DIR
20108
20109         local dir0=$DIR/$tdir/$testnum
20110         mkdir -p $dir0 || error "creating dir $dir0"
20111
20112         local ref1=$dir0/ref1
20113         local ref2=$dir0/ref2
20114         local file1=$dir0/file1
20115         local file2=$dir0/file2
20116         # create a file large enough for the concurrent test
20117         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20118         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20119         echo "ref file size: ref1($(stat -c %s $ref1))," \
20120              "ref2($(stat -c %s $ref2))"
20121
20122         cp $ref2 $file2
20123         dd if=$ref1 of=$file1 bs=16k &
20124         local DD_PID=$!
20125
20126         # Make sure dd starts to copy file, but wait at most 5 seconds
20127         local loops=0
20128         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20129
20130         $LFS swap_layouts $file1 $file2
20131         local rc=$?
20132         wait $DD_PID
20133         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20134         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20135
20136         # how many bytes copied before swapping layout
20137         local copied=$(stat -c %s $file2)
20138         local remaining=$(stat -c %s $ref1)
20139         remaining=$((remaining - copied))
20140         echo "Copied $copied bytes before swapping layout..."
20141
20142         cmp -n $copied $file1 $ref2 | grep differ &&
20143                 error "Content mismatch [0, $copied) of ref2 and file1"
20144         cmp -n $copied $file2 $ref1 ||
20145                 error "Content mismatch [0, $copied) of ref1 and file2"
20146         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20147                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20148
20149         # clean up
20150         rm -f $ref1 $ref2 $file1 $file2
20151 }
20152 run_test 184c "Concurrent write and layout swap"
20153
20154 test_184d() {
20155         check_swap_layouts_support
20156         check_swap_layout_no_dom $DIR
20157         [ -z "$(which getfattr 2>/dev/null)" ] &&
20158                 skip_env "no getfattr command"
20159
20160         local file1=$DIR/$tdir/$tfile-1
20161         local file2=$DIR/$tdir/$tfile-2
20162         local file3=$DIR/$tdir/$tfile-3
20163         local lovea1
20164         local lovea2
20165
20166         mkdir -p $DIR/$tdir
20167         touch $file1 || error "create $file1 failed"
20168         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20169                 error "create $file2 failed"
20170         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20171                 error "create $file3 failed"
20172         lovea1=$(get_layout_param $file1)
20173
20174         $LFS swap_layouts $file2 $file3 ||
20175                 error "swap $file2 $file3 layouts failed"
20176         $LFS swap_layouts $file1 $file2 ||
20177                 error "swap $file1 $file2 layouts failed"
20178
20179         lovea2=$(get_layout_param $file2)
20180         echo "$lovea1"
20181         echo "$lovea2"
20182         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20183
20184         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20185         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20186 }
20187 run_test 184d "allow stripeless layouts swap"
20188
20189 test_184e() {
20190         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20191                 skip "Need MDS version at least 2.6.94"
20192         check_swap_layouts_support
20193         check_swap_layout_no_dom $DIR
20194         [ -z "$(which getfattr 2>/dev/null)" ] &&
20195                 skip_env "no getfattr command"
20196
20197         local file1=$DIR/$tdir/$tfile-1
20198         local file2=$DIR/$tdir/$tfile-2
20199         local file3=$DIR/$tdir/$tfile-3
20200         local lovea
20201
20202         mkdir -p $DIR/$tdir
20203         touch $file1 || error "create $file1 failed"
20204         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20205                 error "create $file2 failed"
20206         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20207                 error "create $file3 failed"
20208
20209         $LFS swap_layouts $file1 $file2 ||
20210                 error "swap $file1 $file2 layouts failed"
20211
20212         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20213         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20214
20215         echo 123 > $file1 || error "Should be able to write into $file1"
20216
20217         $LFS swap_layouts $file1 $file3 ||
20218                 error "swap $file1 $file3 layouts failed"
20219
20220         echo 123 > $file1 || error "Should be able to write into $file1"
20221
20222         rm -rf $file1 $file2 $file3
20223 }
20224 run_test 184e "Recreate layout after stripeless layout swaps"
20225
20226 test_184f() {
20227         # Create a file with name longer than sizeof(struct stat) ==
20228         # 144 to see if we can get chars from the file name to appear
20229         # in the returned striping. Note that 'f' == 0x66.
20230         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20231
20232         mkdir -p $DIR/$tdir
20233         mcreate $DIR/$tdir/$file
20234         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20235                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20236         fi
20237 }
20238 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20239
20240 test_185() { # LU-2441
20241         # LU-3553 - no volatile file support in old servers
20242         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20243                 skip "Need MDS version at least 2.3.60"
20244
20245         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20246         touch $DIR/$tdir/spoo
20247         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20248         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20249                 error "cannot create/write a volatile file"
20250         [ "$FILESET" == "" ] &&
20251         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20252                 error "FID is still valid after close"
20253
20254         multiop_bg_pause $DIR/$tdir Vw4096_c
20255         local multi_pid=$!
20256
20257         local OLD_IFS=$IFS
20258         IFS=":"
20259         local fidv=($fid)
20260         IFS=$OLD_IFS
20261         # assume that the next FID for this client is sequential, since stdout
20262         # is unfortunately eaten by multiop_bg_pause
20263         local n=$((${fidv[1]} + 1))
20264         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20265         if [ "$FILESET" == "" ]; then
20266                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20267                         error "FID is missing before close"
20268         fi
20269         kill -USR1 $multi_pid
20270         # 1 second delay, so if mtime change we will see it
20271         sleep 1
20272         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20273         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20274 }
20275 run_test 185 "Volatile file support"
20276
20277 function create_check_volatile() {
20278         local idx=$1
20279         local tgt
20280
20281         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20282         local PID=$!
20283         sleep 1
20284         local FID=$(cat /tmp/${tfile}.fid)
20285         [ "$FID" == "" ] && error "can't get FID for volatile"
20286         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20287         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20288         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20289         kill -USR1 $PID
20290         wait
20291         sleep 1
20292         cancel_lru_locks mdc # flush opencache
20293         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20294         return 0
20295 }
20296
20297 test_185a(){
20298         # LU-12516 - volatile creation via .lustre
20299         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20300                 skip "Need MDS version at least 2.3.55"
20301
20302         create_check_volatile 0
20303         [ $MDSCOUNT -lt 2 ] && return 0
20304
20305         # DNE case
20306         create_check_volatile 1
20307
20308         return 0
20309 }
20310 run_test 185a "Volatile file creation in .lustre/fid/"
20311
20312 test_187a() {
20313         remote_mds_nodsh && skip "remote MDS with nodsh"
20314         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20315                 skip "Need MDS version at least 2.3.0"
20316
20317         local dir0=$DIR/$tdir/$testnum
20318         mkdir -p $dir0 || error "creating dir $dir0"
20319
20320         local file=$dir0/file1
20321         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20322         stack_trap "rm -f $file"
20323         local dv1=$($LFS data_version $file)
20324         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20325         local dv2=$($LFS data_version $file)
20326         [[ $dv1 != $dv2 ]] ||
20327                 error "data version did not change on write $dv1 == $dv2"
20328 }
20329 run_test 187a "Test data version change"
20330
20331 test_187b() {
20332         remote_mds_nodsh && skip "remote MDS with nodsh"
20333         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20334                 skip "Need MDS version at least 2.3.0"
20335
20336         local dir0=$DIR/$tdir/$testnum
20337         mkdir -p $dir0 || error "creating dir $dir0"
20338
20339         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20340         [[ ${DV[0]} != ${DV[1]} ]] ||
20341                 error "data version did not change on write"\
20342                       " ${DV[0]} == ${DV[1]}"
20343
20344         # clean up
20345         rm -f $file1
20346 }
20347 run_test 187b "Test data version change on volatile file"
20348
20349 test_200() {
20350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20351         remote_mgs_nodsh && skip "remote MGS with nodsh"
20352         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20353
20354         local POOL=${POOL:-cea1}
20355         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20356         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20357         # Pool OST targets
20358         local first_ost=0
20359         local last_ost=$(($OSTCOUNT - 1))
20360         local ost_step=2
20361         local ost_list=$(seq $first_ost $ost_step $last_ost)
20362         local ost_range="$first_ost $last_ost $ost_step"
20363         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20364         local file_dir=$POOL_ROOT/file_tst
20365         local subdir=$test_path/subdir
20366         local rc=0
20367
20368         while : ; do
20369                 # former test_200a test_200b
20370                 pool_add $POOL                          || { rc=$? ; break; }
20371                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20372                 # former test_200c test_200d
20373                 mkdir -p $test_path
20374                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20375                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20376                 mkdir -p $subdir
20377                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20378                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20379                                                         || { rc=$? ; break; }
20380                 # former test_200e test_200f
20381                 local files=$((OSTCOUNT*3))
20382                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20383                                                         || { rc=$? ; break; }
20384                 pool_create_files $POOL $file_dir $files "$ost_list" \
20385                                                         || { rc=$? ; break; }
20386                 # former test_200g test_200h
20387                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20388                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20389
20390                 # former test_201a test_201b test_201c
20391                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20392
20393                 local f=$test_path/$tfile
20394                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20395                 pool_remove $POOL $f                    || { rc=$? ; break; }
20396                 break
20397         done
20398
20399         destroy_test_pools
20400
20401         return $rc
20402 }
20403 run_test 200 "OST pools"
20404
20405 # usage: default_attr <count | size | offset>
20406 default_attr() {
20407         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20408 }
20409
20410 # usage: check_default_stripe_attr
20411 check_default_stripe_attr() {
20412         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20413         case $1 in
20414         --stripe-count|-c)
20415                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20416         --stripe-size|-S)
20417                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20418         --stripe-index|-i)
20419                 EXPECTED=-1;;
20420         *)
20421                 error "unknown getstripe attr '$1'"
20422         esac
20423
20424         [ $ACTUAL == $EXPECTED ] ||
20425                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20426 }
20427
20428 test_204a() {
20429         test_mkdir $DIR/$tdir
20430         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20431
20432         check_default_stripe_attr --stripe-count
20433         check_default_stripe_attr --stripe-size
20434         check_default_stripe_attr --stripe-index
20435 }
20436 run_test 204a "Print default stripe attributes"
20437
20438 test_204b() {
20439         test_mkdir $DIR/$tdir
20440         $LFS setstripe --stripe-count 1 $DIR/$tdir
20441
20442         check_default_stripe_attr --stripe-size
20443         check_default_stripe_attr --stripe-index
20444 }
20445 run_test 204b "Print default stripe size and offset"
20446
20447 test_204c() {
20448         test_mkdir $DIR/$tdir
20449         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20450
20451         check_default_stripe_attr --stripe-count
20452         check_default_stripe_attr --stripe-index
20453 }
20454 run_test 204c "Print default stripe count and offset"
20455
20456 test_204d() {
20457         test_mkdir $DIR/$tdir
20458         $LFS setstripe --stripe-index 0 $DIR/$tdir
20459
20460         check_default_stripe_attr --stripe-count
20461         check_default_stripe_attr --stripe-size
20462 }
20463 run_test 204d "Print default stripe count and size"
20464
20465 test_204e() {
20466         test_mkdir $DIR/$tdir
20467         $LFS setstripe -d $DIR/$tdir
20468
20469         # LU-16904 check if root is set as PFL layout
20470         local numcomp=$($LFS getstripe --component-count $MOUNT)
20471
20472         if [[ $numcomp -gt 0 ]]; then
20473                 check_default_stripe_attr --stripe-count
20474         else
20475                 check_default_stripe_attr --stripe-count --raw
20476         fi
20477         check_default_stripe_attr --stripe-size --raw
20478         check_default_stripe_attr --stripe-index --raw
20479 }
20480 run_test 204e "Print raw stripe attributes"
20481
20482 test_204f() {
20483         test_mkdir $DIR/$tdir
20484         $LFS setstripe --stripe-count 1 $DIR/$tdir
20485
20486         check_default_stripe_attr --stripe-size --raw
20487         check_default_stripe_attr --stripe-index --raw
20488 }
20489 run_test 204f "Print raw stripe size and offset"
20490
20491 test_204g() {
20492         test_mkdir $DIR/$tdir
20493         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20494
20495         check_default_stripe_attr --stripe-count --raw
20496         check_default_stripe_attr --stripe-index --raw
20497 }
20498 run_test 204g "Print raw stripe count and offset"
20499
20500 test_204h() {
20501         test_mkdir $DIR/$tdir
20502         $LFS setstripe --stripe-index 0 $DIR/$tdir
20503
20504         check_default_stripe_attr --stripe-count --raw
20505         check_default_stripe_attr --stripe-size --raw
20506 }
20507 run_test 204h "Print raw stripe count and size"
20508
20509 # Figure out which job scheduler is being used, if any,
20510 # or use a fake one
20511 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20512         JOBENV=SLURM_JOB_ID
20513 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20514         JOBENV=LSB_JOBID
20515 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20516         JOBENV=PBS_JOBID
20517 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20518         JOBENV=LOADL_STEP_ID
20519 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20520         JOBENV=JOB_ID
20521 else
20522         $LCTL list_param jobid_name > /dev/null 2>&1
20523         if [ $? -eq 0 ]; then
20524                 JOBENV=nodelocal
20525         else
20526                 JOBENV=FAKE_JOBID
20527         fi
20528 fi
20529 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20530
20531 verify_jobstats() {
20532         local cmd=($1)
20533         shift
20534         local facets="$@"
20535
20536 # we don't really need to clear the stats for this test to work, since each
20537 # command has a unique jobid, but it makes debugging easier if needed.
20538 #       for facet in $facets; do
20539 #               local dev=$(convert_facet2label $facet)
20540 #               # clear old jobstats
20541 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20542 #       done
20543
20544         # use a new JobID for each test, or we might see an old one
20545         [ "$JOBENV" = "FAKE_JOBID" ] &&
20546                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20547
20548         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20549
20550         [ "$JOBENV" = "nodelocal" ] && {
20551                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20552                 $LCTL set_param jobid_name=$FAKE_JOBID
20553                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20554         }
20555
20556         log "Test: ${cmd[*]}"
20557         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20558
20559         if [ $JOBENV = "FAKE_JOBID" ]; then
20560                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20561         else
20562                 ${cmd[*]}
20563         fi
20564
20565         # all files are created on OST0000
20566         for facet in $facets; do
20567                 local stats="*.$(convert_facet2label $facet).job_stats"
20568
20569                 # strip out libtool wrappers for in-tree executables
20570                 if (( $(do_facet $facet lctl get_param $stats |
20571                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20572                         do_facet $facet lctl get_param $stats
20573                         error "No jobstats for $JOBVAL found on $facet::$stats"
20574                 fi
20575         done
20576 }
20577
20578 jobstats_set() {
20579         local new_jobenv=$1
20580
20581         set_persistent_param_and_check client "jobid_var" \
20582                 "$FSNAME.sys.jobid_var" $new_jobenv
20583 }
20584
20585 test_205a() { # Job stats
20586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20587         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20588                 skip "Need MDS version with at least 2.7.1"
20589         remote_mgs_nodsh && skip "remote MGS with nodsh"
20590         remote_mds_nodsh && skip "remote MDS with nodsh"
20591         remote_ost_nodsh && skip "remote OST with nodsh"
20592         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20593                 skip "Server doesn't support jobstats"
20594         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20595
20596         local old_jobenv=$($LCTL get_param -n jobid_var)
20597         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20598         stack_trap "jobstats_set $old_jobenv" EXIT
20599
20600         changelog_register
20601
20602         local old_jobid_name=$($LCTL get_param jobid_name)
20603         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20604
20605         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20606                                 mdt.*.job_cleanup_interval | head -n 1)
20607         local new_interval=5
20608         do_facet $SINGLEMDS \
20609                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20610         stack_trap "do_facet $SINGLEMDS \
20611                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20612         local start=$SECONDS
20613
20614         local cmd
20615         # mkdir
20616         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20617         verify_jobstats "$cmd" "$SINGLEMDS"
20618         # rmdir
20619         cmd="rmdir $DIR/$tdir"
20620         verify_jobstats "$cmd" "$SINGLEMDS"
20621         # mkdir on secondary MDT
20622         if [ $MDSCOUNT -gt 1 ]; then
20623                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20624                 verify_jobstats "$cmd" "mds2"
20625         fi
20626         # mknod
20627         cmd="mknod $DIR/$tfile c 1 3"
20628         verify_jobstats "$cmd" "$SINGLEMDS"
20629         # unlink
20630         cmd="rm -f $DIR/$tfile"
20631         verify_jobstats "$cmd" "$SINGLEMDS"
20632         # create all files on OST0000 so verify_jobstats can find OST stats
20633         # open & close
20634         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20635         verify_jobstats "$cmd" "$SINGLEMDS"
20636         # setattr
20637         cmd="touch $DIR/$tfile"
20638         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20639         # write
20640         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20641         verify_jobstats "$cmd" "ost1"
20642         # read
20643         cancel_lru_locks osc
20644         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20645         verify_jobstats "$cmd" "ost1"
20646         # truncate
20647         cmd="$TRUNCATE $DIR/$tfile 0"
20648         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20649         # rename
20650         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20651         verify_jobstats "$cmd" "$SINGLEMDS"
20652         # jobstats expiry - sleep until old stats should be expired
20653         local left=$((new_interval + 5 - (SECONDS - start)))
20654         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20655                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20656                         "0" $left
20657         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20658         verify_jobstats "$cmd" "$SINGLEMDS"
20659         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20660             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20661
20662         # Ensure that jobid are present in changelog (if supported by MDS)
20663         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20664                 changelog_dump | tail -10
20665                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20666                 [ $jobids -eq 9 ] ||
20667                         error "Wrong changelog jobid count $jobids != 9"
20668
20669                 # LU-5862
20670                 JOBENV="disable"
20671                 jobstats_set $JOBENV
20672                 touch $DIR/$tfile
20673                 changelog_dump | grep $tfile
20674                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20675                 [ $jobids -eq 0 ] ||
20676                         error "Unexpected jobids when jobid_var=$JOBENV"
20677         fi
20678
20679         # test '%j' access to environment variable - if supported
20680         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20681                 JOBENV="JOBCOMPLEX"
20682                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20683
20684                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20685         fi
20686
20687         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20688                 JOBENV="JOBCOMPLEX"
20689                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20690
20691                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20692         fi
20693
20694         # test '%j' access to per-session jobid - if supported
20695         if lctl list_param jobid_this_session > /dev/null 2>&1
20696         then
20697                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20698                 lctl set_param jobid_this_session=$USER
20699
20700                 JOBENV="JOBCOMPLEX"
20701                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20702
20703                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20704         fi
20705 }
20706 run_test 205a "Verify job stats"
20707
20708 # LU-13117, LU-13597, LU-16599
20709 test_205b() {
20710         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20711                 skip "Need MDS version at least 2.13.54.91"
20712
20713         local job_stats="mdt.*.job_stats"
20714         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20715
20716         do_facet mds1 $LCTL set_param $job_stats=clear
20717
20718         # Setting jobid_var to USER might not be supported
20719         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20720         $LCTL set_param jobid_var=USER || true
20721         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20722         $LCTL set_param jobid_name="%j.%e.%u"
20723
20724         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20725         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20726                 { do_facet mds1 $LCTL get_param $job_stats;
20727                   error "Unexpected jobid found"; }
20728         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20729                 { do_facet mds1 $LCTL get_param $job_stats;
20730                   error "wrong job_stats format found"; }
20731
20732         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20733                 echo "MDS does not yet escape jobid" && return 0
20734
20735         mkdir_on_mdt0 $DIR/$tdir
20736         $LCTL set_param jobid_var=TEST205b
20737         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20738         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20739                       awk '/has\\x20sp/ {print $3}')
20740         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20741                   error "jobid not escaped"; }
20742
20743         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20744                 # need to run such a command on mds1:
20745                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20746                 #
20747                 # there might be multiple MDTs on single mds server, so need to
20748                 # specifiy MDT0000. Or the command will fail due to other MDTs
20749                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20750                         error "cannot clear escaped jobid in job_stats";
20751         else
20752                 echo "MDS does not support clearing escaped jobid"
20753         fi
20754 }
20755 run_test 205b "Verify job stats jobid and output format"
20756
20757 # LU-13733
20758 test_205c() {
20759         $LCTL set_param llite.*.stats=0
20760         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20761         $LCTL get_param llite.*.stats
20762         $LCTL get_param llite.*.stats | grep \
20763                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20764                         error "wrong client stats format found"
20765 }
20766 run_test 205c "Verify client stats format"
20767
20768 test_205d() {
20769         local file=$DIR/$tdir/$tfile
20770
20771         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20772                 skip "need lustre >= 2.15.53 for lljobstat"
20773         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20774                 skip "need lustre >= 2.15.53 for lljobstat"
20775         verify_yaml_available || skip_env "YAML verification not installed"
20776
20777         test_mkdir -i 0 $DIR/$tdir
20778         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20779         stack_trap "rm -rf $DIR/$tdir"
20780
20781         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20782                 error "failed to write data to $file"
20783         mv $file $file.2
20784
20785         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20786         echo -n 'verify rename_stats...'
20787         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20788                 verify_yaml || error "rename_stats is not valid YAML"
20789         echo " OK"
20790
20791         echo -n 'verify mdt job_stats...'
20792         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20793                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20794         echo " OK"
20795
20796         echo -n 'verify ost job_stats...'
20797         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20798                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20799         echo " OK"
20800 }
20801 run_test 205d "verify the format of some stats files"
20802
20803 test_205e() {
20804         local ops_comma
20805         local file=$DIR/$tdir/$tfile
20806         local -a cli_params
20807
20808         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20809                 skip "need lustre >= 2.15.53 for lljobstat"
20810         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20811                 skip "need lustre >= 2.15.53 for lljobstat"
20812         verify_yaml_available || skip_env "YAML verification not installed"
20813
20814         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20815         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20816         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20817
20818         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20819         stack_trap "rm -rf $DIR/$tdir"
20820
20821         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20822                 error "failed to create $file on ost1"
20823         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20824                 error "failed to write data to $file"
20825
20826         do_facet mds1 "$LCTL get_param *.*.job_stats"
20827         do_facet ost1 "$LCTL get_param *.*.job_stats"
20828
20829         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20830         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20831                 error "The output of lljobstat is not an valid YAML"
20832
20833         # verify that job dd.0 does exist and has some ops on ost1
20834         # typically this line is like:
20835         # - 205e.dd.0:            {ops: 20, ...}
20836         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20837                     awk '$2=="205e.dd.0:" {print $4}')
20838
20839         (( ${ops_comma%,} >= 10 )) ||
20840                 error "cannot find job 205e.dd.0 with ops >= 10"
20841 }
20842 run_test 205e "verify the output of lljobstat"
20843
20844 test_205f() {
20845         verify_yaml_available || skip_env "YAML verification not installed"
20846
20847         # check both qos_ost_weights and qos_mdt_weights
20848         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20849         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20850                 error "qos_ost_weights is not valid YAML"
20851 }
20852 run_test 205f "verify qos_ost_weights YAML format "
20853
20854 __test_205_jobstats_dump() {
20855         local -a pids
20856         local nbr_instance=$1
20857
20858         while true; do
20859                 if (( ${#pids[@]} >= nbr_instance )); then
20860                         wait ${pids[@]}
20861                         pids=()
20862                 fi
20863
20864                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20865                 pids+=( $! )
20866         done
20867 }
20868
20869 __test_205_cleanup() {
20870         kill $@
20871         # Clear all job entries
20872         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20873 }
20874
20875 test_205g() {
20876         local -a mds1_params
20877         local -a cli_params
20878         local pids
20879         local interval=5
20880
20881         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20882         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20883         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20884
20885         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20886         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20887         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20888
20889         # start jobs loop
20890         export TEST205G_ID=205g
20891         stack_trap "unset TEST205G_ID" EXIT
20892         while true; do
20893                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20894         done & pids="$! "
20895
20896         __test_205_jobstats_dump 4 & pids+="$! "
20897         stack_trap "__test_205_cleanup $pids" EXIT INT
20898
20899         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20900 }
20901 run_test 205g "stress test for job_stats procfile"
20902
20903 test_205h() {
20904         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20905                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20906         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20907
20908         local dir=$DIR/$tdir
20909         local f=$dir/$tfile
20910         local f2=$dir/$tfile-2
20911         local f3=$dir/$tfile-3
20912         local subdir=$DIR/dir
20913         local val
20914
20915         local mdts=$(comma_list $(mdts_nodes))
20916         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20917         local client_saved=$($LCTL get_param -n jobid_var)
20918
20919         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20920         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20921
20922         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20923                 error "failed to set job_xattr parameter to user.job"
20924         $LCTL set_param jobid_var=procname.uid ||
20925                 error "failed to set jobid_var parameter"
20926
20927         test_mkdir $dir
20928
20929         touch $f
20930         val=$(getfattr -n user.job $f | grep user.job)
20931         [[ $val = user.job=\"touch.0\" ]] ||
20932                 error "expected user.job=\"touch.0\", got '$val'"
20933
20934         mkdir $subdir
20935         val=$(getfattr -n user.job $subdir | grep user.job)
20936         [[ $val = user.job=\"mkdir.0\" ]] ||
20937                 error "expected user.job=\"mkdir.0\", got '$val'"
20938
20939         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20940                 error "failed to set job_xattr parameter to NONE"
20941
20942         touch $f2
20943         val=$(getfattr -d $f2)
20944         [[ -z $val ]] ||
20945                 error "expected no user xattr, got '$val'"
20946
20947         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20948                 error "failed to set job_xattr parameter to trusted.job"
20949
20950         touch $f3
20951         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20952         [[ $val = trusted.job=\"touch.0\" ]] ||
20953                 error "expected trusted.job=\"touch.0\", got '$val'"
20954 }
20955 run_test 205h "check jobid xattr is stored correctly"
20956
20957 test_205i() {
20958         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20959                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20960
20961         local mdts=$(comma_list $(mdts_nodes))
20962         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20963
20964         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20965
20966         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20967                 error "failed to set mdt.*.job_xattr to user.1234567"
20968
20969         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20970                 error "failed to reject too long job_xattr name"
20971
20972         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20973                 error "failed to reject job_xattr name in bad format"
20974
20975         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20976                 error "failed to reject job_xattr name with invalid character"
20977
20978         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20979                         xargs $LCTL set_param" &&
20980                 error "failed to reject job_xattr name with non-ascii character"
20981
20982         return 0
20983 }
20984 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20985
20986 # LU-1480, LU-1773 and LU-1657
20987 test_206() {
20988         mkdir -p $DIR/$tdir
20989         $LFS setstripe -c -1 $DIR/$tdir
20990 #define OBD_FAIL_LOV_INIT 0x1403
20991         $LCTL set_param fail_loc=0xa0001403
20992         $LCTL set_param fail_val=1
20993         touch $DIR/$tdir/$tfile || true
20994 }
20995 run_test 206 "fail lov_init_raid0() doesn't lbug"
20996
20997 test_207a() {
20998         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20999         local fsz=`stat -c %s $DIR/$tfile`
21000         cancel_lru_locks mdc
21001
21002         # do not return layout in getattr intent
21003 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
21004         $LCTL set_param fail_loc=0x170
21005         local sz=`stat -c %s $DIR/$tfile`
21006
21007         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
21008
21009         rm -rf $DIR/$tfile
21010 }
21011 run_test 207a "can refresh layout at glimpse"
21012
21013 test_207b() {
21014         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
21015         local cksum=`md5sum $DIR/$tfile`
21016         local fsz=`stat -c %s $DIR/$tfile`
21017         cancel_lru_locks mdc
21018         cancel_lru_locks osc
21019
21020         # do not return layout in getattr intent
21021 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
21022         $LCTL set_param fail_loc=0x171
21023
21024         # it will refresh layout after the file is opened but before read issues
21025         echo checksum is "$cksum"
21026         echo "$cksum" |md5sum -c --quiet || error "file differs"
21027
21028         rm -rf $DIR/$tfile
21029 }
21030 run_test 207b "can refresh layout at open"
21031
21032 test_208() {
21033         # FIXME: in this test suite, only RD lease is used. This is okay
21034         # for now as only exclusive open is supported. After generic lease
21035         # is done, this test suite should be revised. - Jinshan
21036
21037         remote_mds_nodsh && skip "remote MDS with nodsh"
21038         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21039                 skip "Need MDS version at least 2.4.52"
21040
21041         echo "==== test 1: verify get lease work"
21042         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21043
21044         echo "==== test 2: verify lease can be broken by upcoming open"
21045         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21046         local PID=$!
21047         sleep 2
21048
21049         $MULTIOP $DIR/$tfile oO_RDWR:c
21050         kill -USR1 $PID && wait $PID || error "break lease error"
21051
21052         echo "==== test 3: verify lease can't be granted if an open already exists"
21053         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21054         local PID=$!
21055         sleep 2
21056
21057         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21058         kill -USR1 $PID && wait $PID || error "open file error"
21059
21060         echo "==== test 4: lease can sustain over recovery"
21061         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21062         PID=$!
21063         sleep 2
21064
21065         fail mds1
21066
21067         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21068
21069         echo "==== test 5: lease broken can't be regained by replay"
21070         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21071         PID=$!
21072         sleep 2
21073
21074         # open file to break lease and then recovery
21075         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21076         fail mds1
21077
21078         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21079
21080         rm -f $DIR/$tfile
21081 }
21082 run_test 208 "Exclusive open"
21083
21084 test_209() {
21085         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21086                 skip_env "must have disp_stripe"
21087
21088         touch $DIR/$tfile
21089         sync; sleep 5; sync;
21090
21091         echo 3 > /proc/sys/vm/drop_caches
21092         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21093                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21094         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21095
21096         # open/close 500 times
21097         for i in $(seq 500); do
21098                 cat $DIR/$tfile
21099         done
21100
21101         echo 3 > /proc/sys/vm/drop_caches
21102         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21103                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21104         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21105
21106         echo "before: $req_before, after: $req_after"
21107         [ $((req_after - req_before)) -ge 300 ] &&
21108                 error "open/close requests are not freed"
21109         return 0
21110 }
21111 run_test 209 "read-only open/close requests should be freed promptly"
21112
21113 test_210() {
21114         local pid
21115
21116         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21117         pid=$!
21118         sleep 1
21119
21120         $LFS getstripe $DIR/$tfile
21121         kill -USR1 $pid
21122         wait $pid || error "multiop failed"
21123
21124         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21125         pid=$!
21126         sleep 1
21127
21128         $LFS getstripe $DIR/$tfile
21129         kill -USR1 $pid
21130         wait $pid || error "multiop failed"
21131 }
21132 run_test 210 "lfs getstripe does not break leases"
21133
21134 function test_211() {
21135         local PID
21136         local id
21137         local rc
21138
21139         stack_trap "rm -f $DIR/$tfile" EXIT
21140         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21141                 error "can't create file"
21142         $LFS mirror extend -N $DIR/$tfile ||
21143                 error "can't create a replica"
21144         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21145         $LFS getstripe $DIR/$tfile
21146         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21147         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21148
21149         $MULTIOP $DIR/$tfile OeW_E+eUc &
21150         PID=$!
21151         sleep 0.3
21152
21153         id=$($LFS getstripe $DIR/$tfile |
21154                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21155         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21156                 error "removed last in-sync replica?"
21157
21158         kill -USR1 $PID
21159         wait $PID
21160         (( $? == 0 )) || error "failed split broke the lease"
21161 }
21162 run_test 211 "failed mirror split doesn't break write lease"
21163
21164 test_212() {
21165         size=`date +%s`
21166         size=$((size % 8192 + 1))
21167         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21168         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21169         rm -f $DIR/f212 $DIR/f212.xyz
21170 }
21171 run_test 212 "Sendfile test ============================================"
21172
21173 test_213() {
21174         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21175         cancel_lru_locks osc
21176         lctl set_param fail_loc=0x8000040f
21177         # generate a read lock
21178         cat $DIR/$tfile > /dev/null
21179         # write to the file, it will try to cancel the above read lock.
21180         cat /etc/hosts >> $DIR/$tfile
21181 }
21182 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21183
21184 test_214() { # for bug 20133
21185         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21186         for (( i=0; i < 340; i++ )) ; do
21187                 touch $DIR/$tdir/d214c/a$i
21188         done
21189
21190         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21191         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21192         ls $DIR/d214c || error "ls $DIR/d214c failed"
21193         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21194         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21195 }
21196 run_test 214 "hash-indexed directory test - bug 20133"
21197
21198 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21199 create_lnet_proc_files() {
21200         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21201 }
21202
21203 # counterpart of create_lnet_proc_files
21204 remove_lnet_proc_files() {
21205         rm -f $TMP/lnet_$1.sys
21206 }
21207
21208 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21209 # 3rd arg as regexp for body
21210 check_lnet_proc_stats() {
21211         local l=$(cat "$TMP/lnet_$1" |wc -l)
21212         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21213
21214         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21215 }
21216
21217 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21218 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21219 # optional and can be regexp for 2nd line (lnet.routes case)
21220 check_lnet_proc_entry() {
21221         local blp=2          # blp stands for 'position of 1st line of body'
21222         [ -z "$5" ] || blp=3 # lnet.routes case
21223
21224         local l=$(cat "$TMP/lnet_$1" |wc -l)
21225         # subtracting one from $blp because the body can be empty
21226         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21227
21228         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21229                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21230
21231         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21232                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21233
21234         # bail out if any unexpected line happened
21235         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21236         [ "$?" != 0 ] || error "$2 misformatted"
21237 }
21238
21239 test_215() { # for bugs 18102, 21079, 21517
21240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21241
21242         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21243         local P='[1-9][0-9]*'           # positive numeric
21244         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21245         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21246         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21247         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21248         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21249         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21250
21251         local L1 # regexp for 1st line
21252         local L2 # regexp for 2nd line (optional)
21253         local BR # regexp for the rest (body)
21254
21255         # lnet.stats should look as 11 space-separated non-negative numerics
21256         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21257         create_lnet_proc_files "stats"
21258         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21259         remove_lnet_proc_files "stats"
21260
21261         # lnet.routes should look like this:
21262         # Routing disabled/enabled
21263         # net hops priority state router
21264         # where net is a string like tcp0, hops > 0, priority >= 0,
21265         # state is up/down,
21266         # router is a string like 192.168.1.1@tcp2
21267         L1="^Routing (disabled|enabled)$"
21268         L2="^net +hops +priority +state +router$"
21269         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21270         create_lnet_proc_files "routes"
21271         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21272         remove_lnet_proc_files "routes"
21273
21274         # lnet.routers should look like this:
21275         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21276         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21277         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21278         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21279         L1="^ref +rtr_ref +alive +router$"
21280         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21281         create_lnet_proc_files "routers"
21282         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21283         remove_lnet_proc_files "routers"
21284
21285         # lnet.peers should look like this:
21286         # nid refs state last max rtr min tx min queue
21287         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21288         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21289         # numeric (0 or >0 or <0), queue >= 0.
21290         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21291         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21292         create_lnet_proc_files "peers"
21293         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21294         remove_lnet_proc_files "peers"
21295
21296         # lnet.buffers  should look like this:
21297         # pages count credits min
21298         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21299         L1="^pages +count +credits +min$"
21300         BR="^ +$N +$N +$I +$I$"
21301         create_lnet_proc_files "buffers"
21302         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21303         remove_lnet_proc_files "buffers"
21304
21305         # lnet.nis should look like this:
21306         # nid status alive refs peer rtr max tx min
21307         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21308         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21309         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21310         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21311         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21312         create_lnet_proc_files "nis"
21313         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21314         remove_lnet_proc_files "nis"
21315
21316         # can we successfully write to lnet.stats?
21317         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21318 }
21319 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21320
21321 test_216() { # bug 20317
21322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21323         remote_ost_nodsh && skip "remote OST with nodsh"
21324
21325         local node
21326         local facets=$(get_facets OST)
21327         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21328
21329         save_lustre_params client "osc.*.contention_seconds" > $p
21330         save_lustre_params $facets \
21331                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21332         save_lustre_params $facets \
21333                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21334         save_lustre_params $facets \
21335                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21336         clear_stats osc.*.osc_stats
21337
21338         # agressive lockless i/o settings
21339         do_nodes $(comma_list $(osts_nodes)) \
21340                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21341                         ldlm.namespaces.filter-*.contended_locks=0 \
21342                         ldlm.namespaces.filter-*.contention_seconds=60"
21343         lctl set_param -n osc.*.contention_seconds=60
21344
21345         $DIRECTIO write $DIR/$tfile 0 10 4096
21346         $CHECKSTAT -s 40960 $DIR/$tfile
21347
21348         # disable lockless i/o
21349         do_nodes $(comma_list $(osts_nodes)) \
21350                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21351                         ldlm.namespaces.filter-*.contended_locks=32 \
21352                         ldlm.namespaces.filter-*.contention_seconds=0"
21353         lctl set_param -n osc.*.contention_seconds=0
21354         clear_stats osc.*.osc_stats
21355
21356         dd if=/dev/zero of=$DIR/$tfile count=0
21357         $CHECKSTAT -s 0 $DIR/$tfile
21358
21359         restore_lustre_params <$p
21360         rm -f $p
21361         rm $DIR/$tfile
21362 }
21363 run_test 216 "check lockless direct write updates file size and kms correctly"
21364
21365 test_217() { # bug 22430
21366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21367
21368         local node
21369
21370         for node in $(nodes_list); do
21371                 local nid=$(host_nids_address $node $NETTYPE)
21372                 local node_ip=$(do_node $node getent ahostsv4 $node |
21373                                 awk '{ print $1; exit; }')
21374
21375                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21376                 # if hostname matches any NID, use hostname for better testing
21377                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21378                         echo "lctl ping node $node@$NETTYPE"
21379                         lctl ping $node@$NETTYPE ||
21380                                 error "ping $node@$NETTYPE failed rc=$?"
21381                 else # otherwise, at least test 'lctl ping' is working
21382                         echo "lctl ping nid $(h2nettype $nid)"
21383                         lctl ping $(h2nettype $nid) ||
21384                                 error "ping $(h2nettype $nid) failed rc=$?"
21385                         echo "skipping $node (no hyphen detected)"
21386                 fi
21387         done
21388
21389         return 0
21390 }
21391 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21392
21393 test_218() {
21394         # do directio so as not to populate the page cache
21395         log "creating a 10 Mb file"
21396         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21397                 error "multiop failed while creating a file"
21398         log "starting reads"
21399         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21400         log "truncating the file"
21401         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21402                 error "multiop failed while truncating the file"
21403         log "killing dd"
21404         kill %+ || true # reads might have finished
21405         echo "wait until dd is finished"
21406         wait
21407         log "removing the temporary file"
21408         rm -rf $DIR/$tfile || error "tmp file removal failed"
21409 }
21410 run_test 218 "parallel read and truncate should not deadlock"
21411
21412 test_219() {
21413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21414
21415         # write one partial page
21416         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21417         # set no grant so vvp_io_commit_write will do sync write
21418         $LCTL set_param fail_loc=0x411
21419         # write a full page at the end of file
21420         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21421
21422         $LCTL set_param fail_loc=0
21423         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21424         $LCTL set_param fail_loc=0x411
21425         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21426
21427         # LU-4201
21428         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21429         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21430 }
21431 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21432
21433 test_220() { #LU-325
21434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21435         remote_ost_nodsh && skip "remote OST with nodsh"
21436         remote_mds_nodsh && skip "remote MDS with nodsh"
21437         remote_mgs_nodsh && skip "remote MGS with nodsh"
21438
21439         local OSTIDX=0
21440
21441         # create on MDT0000 so the last_id and next_id are correct
21442         mkdir_on_mdt0 $DIR/$tdir
21443         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21444         OST=${OST%_UUID}
21445
21446         # on the mdt's osc
21447         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21448         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21449                         osp.$mdtosc_proc1.prealloc_last_id)
21450         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21451                         osp.$mdtosc_proc1.prealloc_next_id)
21452
21453         $LFS df -i
21454
21455         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21456         #define OBD_FAIL_OST_ENOINO              0x229
21457         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21458         create_pool $FSNAME.$TESTNAME || return 1
21459         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21460
21461         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21462
21463         MDSOBJS=$((last_id - next_id))
21464         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21465
21466         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21467         echo "OST still has $count kbytes free"
21468
21469         echo "create $MDSOBJS files @next_id..."
21470         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21471
21472         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21473                         osp.$mdtosc_proc1.prealloc_last_id)
21474         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21475                         osp.$mdtosc_proc1.prealloc_next_id)
21476
21477         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21478         $LFS df -i
21479
21480         echo "cleanup..."
21481
21482         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21483         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21484
21485         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21486                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21487         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21488                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21489         echo "unlink $MDSOBJS files @$next_id..."
21490         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21491 }
21492 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21493
21494 test_221() {
21495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21496
21497         dd if=`which date` of=$MOUNT/date oflag=sync
21498         chmod +x $MOUNT/date
21499
21500         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21501         $LCTL set_param fail_loc=0x80001401
21502
21503         $MOUNT/date > /dev/null
21504         rm -f $MOUNT/date
21505 }
21506 run_test 221 "make sure fault and truncate race to not cause OOM"
21507
21508 test_222a () {
21509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21510
21511         rm -rf $DIR/$tdir
21512         test_mkdir $DIR/$tdir
21513         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21514         createmany -o $DIR/$tdir/$tfile 10
21515         cancel_lru_locks mdc
21516         cancel_lru_locks osc
21517         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21518         $LCTL set_param fail_loc=0x31a
21519         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21520         $LCTL set_param fail_loc=0
21521         rm -r $DIR/$tdir
21522 }
21523 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21524
21525 test_222b () {
21526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21527
21528         rm -rf $DIR/$tdir
21529         test_mkdir $DIR/$tdir
21530         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21531         createmany -o $DIR/$tdir/$tfile 10
21532         cancel_lru_locks mdc
21533         cancel_lru_locks osc
21534         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21535         $LCTL set_param fail_loc=0x31a
21536         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21537         $LCTL set_param fail_loc=0
21538 }
21539 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21540
21541 test_223 () {
21542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21543
21544         rm -rf $DIR/$tdir
21545         test_mkdir $DIR/$tdir
21546         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21547         createmany -o $DIR/$tdir/$tfile 10
21548         cancel_lru_locks mdc
21549         cancel_lru_locks osc
21550         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21551         $LCTL set_param fail_loc=0x31b
21552         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21553         $LCTL set_param fail_loc=0
21554         rm -r $DIR/$tdir
21555 }
21556 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21557
21558 test_224a() { # LU-1039, MRP-303
21559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21560         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21561         $LCTL set_param fail_loc=0x508
21562         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21563         $LCTL set_param fail_loc=0
21564         df $DIR
21565 }
21566 run_test 224a "Don't panic on bulk IO failure"
21567
21568 test_224bd_sub() { # LU-1039, MRP-303
21569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21570         local timeout=$1
21571
21572         shift
21573         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21574
21575         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21576
21577         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21578         cancel_lru_locks osc
21579         set_checksums 0
21580         stack_trap "set_checksums $ORIG_CSUM" EXIT
21581         local at_max_saved=0
21582
21583         # adaptive timeouts may prevent seeing the issue
21584         if at_is_enabled; then
21585                 at_max_saved=$(at_max_get mds)
21586                 at_max_set 0 mds client
21587                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21588         fi
21589
21590         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21591         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21592         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21593
21594         do_facet ost1 $LCTL set_param fail_loc=0
21595         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21596         df $DIR
21597 }
21598
21599 test_224b() {
21600         test_224bd_sub 3 error "dd failed"
21601 }
21602 run_test 224b "Don't panic on bulk IO failure"
21603
21604 test_224c() { # LU-6441
21605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21606         remote_mds_nodsh && skip "remote MDS with nodsh"
21607
21608         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21609         save_writethrough $p
21610         set_cache writethrough on
21611
21612         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21613         local at_max=$($LCTL get_param -n at_max)
21614         local timeout=$($LCTL get_param -n timeout)
21615         local test_at="at_max"
21616         local param_at="$FSNAME.sys.at_max"
21617         local test_timeout="timeout"
21618         local param_timeout="$FSNAME.sys.timeout"
21619
21620         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21621
21622         set_persistent_param_and_check client "$test_at" "$param_at" 0
21623         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21624
21625         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21626         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21627         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21628         stack_trap "rm -f $DIR/$tfile"
21629         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21630         sync
21631         do_facet ost1 "$LCTL set_param fail_loc=0"
21632
21633         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21634         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21635                 $timeout
21636
21637         $LCTL set_param -n $pages_per_rpc
21638         restore_lustre_params < $p
21639         rm -f $p
21640 }
21641 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21642
21643 test_224d() { # LU-11169
21644         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21645 }
21646 run_test 224d "Don't corrupt data on bulk IO timeout"
21647
21648 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21649 test_225a () {
21650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21651         if [ -z ${MDSSURVEY} ]; then
21652                 skip_env "mds-survey not found"
21653         fi
21654         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21655                 skip "Need MDS version at least 2.2.51"
21656
21657         local mds=$(facet_host $SINGLEMDS)
21658         local target=$(do_nodes $mds 'lctl dl' |
21659                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21660
21661         local cmd1="file_count=1000 thrhi=4"
21662         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21663         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21664         local cmd="$cmd1 $cmd2 $cmd3"
21665
21666         rm -f ${TMP}/mds_survey*
21667         echo + $cmd
21668         eval $cmd || error "mds-survey with zero-stripe failed"
21669         cat ${TMP}/mds_survey*
21670         rm -f ${TMP}/mds_survey*
21671 }
21672 run_test 225a "Metadata survey sanity with zero-stripe"
21673
21674 test_225b () {
21675         if [ -z ${MDSSURVEY} ]; then
21676                 skip_env "mds-survey not found"
21677         fi
21678         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21679                 skip "Need MDS version at least 2.2.51"
21680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21681         remote_mds_nodsh && skip "remote MDS with nodsh"
21682         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21683                 skip_env "Need to mount OST to test"
21684         fi
21685
21686         local mds=$(facet_host $SINGLEMDS)
21687         local target=$(do_nodes $mds 'lctl dl' |
21688                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21689
21690         local cmd1="file_count=1000 thrhi=4"
21691         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21692         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21693         local cmd="$cmd1 $cmd2 $cmd3"
21694
21695         rm -f ${TMP}/mds_survey*
21696         echo + $cmd
21697         eval $cmd || error "mds-survey with stripe_count failed"
21698         cat ${TMP}/mds_survey*
21699         rm -f ${TMP}/mds_survey*
21700 }
21701 run_test 225b "Metadata survey sanity with stripe_count = 1"
21702
21703 mcreate_path2fid () {
21704         local mode=$1
21705         local major=$2
21706         local minor=$3
21707         local name=$4
21708         local desc=$5
21709         local path=$DIR/$tdir/$name
21710         local fid
21711         local rc
21712         local fid_path
21713
21714         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21715                 error "cannot create $desc"
21716
21717         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21718         rc=$?
21719         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21720
21721         fid_path=$($LFS fid2path $MOUNT $fid)
21722         rc=$?
21723         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21724
21725         [ "$path" == "$fid_path" ] ||
21726                 error "fid2path returned $fid_path, expected $path"
21727
21728         echo "pass with $path and $fid"
21729 }
21730
21731 test_226a () {
21732         rm -rf $DIR/$tdir
21733         mkdir -p $DIR/$tdir
21734
21735         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21736         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21737         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21738         mcreate_path2fid 0040666 0 0 dir "directory"
21739         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21740         mcreate_path2fid 0100666 0 0 file "regular file"
21741         mcreate_path2fid 0120666 0 0 link "symbolic link"
21742         mcreate_path2fid 0140666 0 0 sock "socket"
21743 }
21744 run_test 226a "call path2fid and fid2path on files of all type"
21745
21746 test_226b () {
21747         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21748
21749         local MDTIDX=1
21750
21751         rm -rf $DIR/$tdir
21752         mkdir -p $DIR/$tdir
21753         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21754                 error "create remote directory failed"
21755         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21756         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21757                                 "character special file (null)"
21758         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21759                                 "character special file (no device)"
21760         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21761         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21762                                 "block special file (loop)"
21763         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21764         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21765         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21766 }
21767 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21768
21769 test_226c () {
21770         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21771         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21772                 skip "Need MDS version at least 2.13.55"
21773
21774         local submnt=/mnt/submnt
21775         local srcfile=/etc/passwd
21776         local dstfile=$submnt/passwd
21777         local path
21778         local fid
21779
21780         rm -rf $DIR/$tdir
21781         rm -rf $submnt
21782         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21783                 error "create remote directory failed"
21784         mkdir -p $submnt || error "create $submnt failed"
21785         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21786                 error "mount $submnt failed"
21787         stack_trap "umount $submnt" EXIT
21788
21789         cp $srcfile $dstfile
21790         fid=$($LFS path2fid $dstfile)
21791         path=$($LFS fid2path $submnt "$fid")
21792         [ "$path" = "$dstfile" ] ||
21793                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21794 }
21795 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21796
21797 test_226d () {
21798         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21799                 skip "Need client at least version 2.15.57"
21800
21801         # Define First test dataset
21802         local testdirs_01=$DIR/$tdir
21803         local testdata_01=$testdirs_01/${tdir}_01
21804         local testresult_01=${tdir}_01
21805         # Define Second test dataset
21806         local testdirs_02=$DIR/$tdir/$tdir
21807         local testdata_02=$testdirs_02/${tdir}_02
21808         local testresult_02=${tdir}_02
21809         # Define third test dataset (top level)
21810         local testdata_03=$DIR/${tdir}_03
21811         local testresult_03=${tdir}_03
21812
21813         # Create first test dataset
21814         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21815         touch $testdata_01 || error "cannot create file $testdata_01"
21816
21817         # Create second test dataset
21818         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21819         touch $testdata_02 || error "cannot create file $testdata_02"
21820
21821         # Create third test dataset
21822         touch $testdata_03 || error "cannot create file $testdata_03"
21823
21824         local fid01=$($LFS getstripe -F "$testdata_01") ||
21825                 error "getstripe failed on $testdata_01"
21826         local fid02=$($LFS getstripe -F "$testdata_02") ||
21827                 error "getstripe failed on $testdata_01"
21828         local fid03=$($LFS getstripe -F "$testdata_03") ||
21829                 error "getstripe failed on $testdata_03"
21830
21831         # Verify only -n option
21832         local out1=$($LFS fid2path -n $DIR $fid01) ||
21833                 error "fid2path failed on $fid01"
21834         local out2=$($LFS fid2path -n $DIR $fid02) ||
21835                 error "fid2path failed on $fid02"
21836         local out3=$($LFS fid2path -n $DIR $fid03) ||
21837                 error "fid2path failed on $fid03"
21838
21839         [[ "$out1" == "$testresult_01" ]] ||
21840                 error "fid2path failed: Expected $testresult_01 got $out1"
21841         [[ "$out2" == "$testresult_02" ]] ||
21842                 error "fid2path failed: Expected $testresult_02 got $out2"
21843         [[ "$out3" == "$testresult_03" ]] ||
21844                 error "fid2path failed: Expected $testresult_03 got $out3"
21845
21846         # Verify with option -fn together
21847         out1=$($LFS fid2path -fn $DIR $fid01) ||
21848                 error "fid2path -fn failed on $fid01"
21849         out2=$($LFS fid2path -fn $DIR $fid02) ||
21850                 error "fid2path -fn failed on $fid02"
21851         out3=$($LFS fid2path -fn $DIR $fid03) ||
21852                 error "fid2path -fn failed on $fid03"
21853
21854         local tmpout=$(echo $out1 | cut -d" " -f2)
21855         [[ "$tmpout" == "$testresult_01" ]] ||
21856                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21857
21858         tmpout=$(echo $out2 | cut -d" " -f2)
21859         [[ "$tmpout" == "$testresult_02" ]] ||
21860                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21861
21862         tmpout=$(echo $out3 | cut -d" " -f2)
21863         [[ "$tmpout" == "$testresult_03" ]] ||
21864                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21865 }
21866 run_test 226d "verify fid2path with -n and -fn option"
21867
21868 test_226e () {
21869         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21870                 skip "Need client at least version 2.15.56"
21871
21872         # Define filename with 'newline' and a space
21873         local testfile="Test"$'\n'"file 01"
21874         # Define link name with multiple 'newline' and a space
21875         local linkfile="Link"$'\n'"file "$'\n'"01"
21876         # Remove prior hard link
21877         rm -f $DIR/"$linkfile"
21878
21879         # Create file
21880         touch $DIR/"$testfile"
21881         # Create link
21882         ln $DIR/"$testfile" $DIR/"$linkfile"
21883
21884         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21885                 error "getstripe failed on $DIR/$testfile"
21886
21887         # Call with -0 option
21888         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21889                 echo "FILE:" | grep -c "FILE:")
21890
21891         # With -0 option the output should be exactly 2 lines.
21892         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21893 }
21894 run_test 226e "Verify path2fid -0 option with newline and space"
21895
21896 # LU-1299 Executing or running ldd on a truncated executable does not
21897 # cause an out-of-memory condition.
21898 test_227() {
21899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21900         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21901
21902         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21903         chmod +x $MOUNT/date
21904
21905         $MOUNT/date > /dev/null
21906         ldd $MOUNT/date > /dev/null
21907         rm -f $MOUNT/date
21908 }
21909 run_test 227 "running truncated executable does not cause OOM"
21910
21911 # LU-1512 try to reuse idle OI blocks
21912 test_228a() {
21913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21914         remote_mds_nodsh && skip "remote MDS with nodsh"
21915         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21916
21917         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21918         local myDIR=$DIR/$tdir
21919
21920         mkdir -p $myDIR
21921         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21922         $LCTL set_param fail_loc=0x80001002
21923         createmany -o $myDIR/t- 10000
21924         $LCTL set_param fail_loc=0
21925         # The guard is current the largest FID holder
21926         touch $myDIR/guard
21927         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21928                     tr -d '[')
21929         local IDX=$(($SEQ % 64))
21930
21931         do_facet $SINGLEMDS sync
21932         # Make sure journal flushed.
21933         sleep 6
21934         local blk1=$(do_facet $SINGLEMDS \
21935                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21936                      grep Blockcount | awk '{print $4}')
21937
21938         # Remove old files, some OI blocks will become idle.
21939         unlinkmany $myDIR/t- 10000
21940         # Create new files, idle OI blocks should be reused.
21941         createmany -o $myDIR/t- 2000
21942         do_facet $SINGLEMDS sync
21943         # Make sure journal flushed.
21944         sleep 6
21945         local blk2=$(do_facet $SINGLEMDS \
21946                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21947                      grep Blockcount | awk '{print $4}')
21948
21949         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21950 }
21951 run_test 228a "try to reuse idle OI blocks"
21952
21953 test_228b() {
21954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21955         remote_mds_nodsh && skip "remote MDS with nodsh"
21956         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21957
21958         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21959         local myDIR=$DIR/$tdir
21960
21961         mkdir -p $myDIR
21962         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21963         $LCTL set_param fail_loc=0x80001002
21964         createmany -o $myDIR/t- 10000
21965         $LCTL set_param fail_loc=0
21966         # The guard is current the largest FID holder
21967         touch $myDIR/guard
21968         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21969                     tr -d '[')
21970         local IDX=$(($SEQ % 64))
21971
21972         do_facet $SINGLEMDS sync
21973         # Make sure journal flushed.
21974         sleep 6
21975         local blk1=$(do_facet $SINGLEMDS \
21976                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21977                      grep Blockcount | awk '{print $4}')
21978
21979         # Remove old files, some OI blocks will become idle.
21980         unlinkmany $myDIR/t- 10000
21981
21982         # stop the MDT
21983         stop $SINGLEMDS || error "Fail to stop MDT."
21984         # remount the MDT
21985         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21986                 error "Fail to start MDT."
21987
21988         client_up || error "Fail to df."
21989         # Create new files, idle OI blocks should be reused.
21990         createmany -o $myDIR/t- 2000
21991         do_facet $SINGLEMDS sync
21992         # Make sure journal flushed.
21993         sleep 6
21994         local blk2=$(do_facet $SINGLEMDS \
21995                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21996                      grep Blockcount | awk '{print $4}')
21997
21998         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21999 }
22000 run_test 228b "idle OI blocks can be reused after MDT restart"
22001
22002 #LU-1881
22003 test_228c() {
22004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22005         remote_mds_nodsh && skip "remote MDS with nodsh"
22006         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
22007
22008         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
22009         local myDIR=$DIR/$tdir
22010
22011         mkdir -p $myDIR
22012         #define OBD_FAIL_SEQ_EXHAUST             0x1002
22013         $LCTL set_param fail_loc=0x80001002
22014         # 20000 files can guarantee there are index nodes in the OI file
22015         createmany -o $myDIR/t- 20000
22016         $LCTL set_param fail_loc=0
22017         # The guard is current the largest FID holder
22018         touch $myDIR/guard
22019         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
22020                     tr -d '[')
22021         local IDX=$(($SEQ % 64))
22022
22023         do_facet $SINGLEMDS sync
22024         # Make sure journal flushed.
22025         sleep 6
22026         local blk1=$(do_facet $SINGLEMDS \
22027                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22028                      grep Blockcount | awk '{print $4}')
22029
22030         # Remove old files, some OI blocks will become idle.
22031         unlinkmany $myDIR/t- 20000
22032         rm -f $myDIR/guard
22033         # The OI file should become empty now
22034
22035         # Create new files, idle OI blocks should be reused.
22036         createmany -o $myDIR/t- 2000
22037         do_facet $SINGLEMDS sync
22038         # Make sure journal flushed.
22039         sleep 6
22040         local blk2=$(do_facet $SINGLEMDS \
22041                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22042                      grep Blockcount | awk '{print $4}')
22043
22044         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22045 }
22046 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22047
22048 test_229() { # LU-2482, LU-3448
22049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22050         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22051         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22052                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22053
22054         rm -f $DIR/$tfile
22055
22056         # Create a file with a released layout and stripe count 2.
22057         $MULTIOP $DIR/$tfile H2c ||
22058                 error "failed to create file with released layout"
22059
22060         $LFS getstripe -v $DIR/$tfile
22061
22062         local pattern=$($LFS getstripe -L $DIR/$tfile)
22063         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22064
22065         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22066                 error "getstripe"
22067         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22068         stat $DIR/$tfile || error "failed to stat released file"
22069
22070         chown $RUNAS_ID $DIR/$tfile ||
22071                 error "chown $RUNAS_ID $DIR/$tfile failed"
22072
22073         chgrp $RUNAS_ID $DIR/$tfile ||
22074                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22075
22076         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22077         rm $DIR/$tfile || error "failed to remove released file"
22078 }
22079 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22080
22081 test_230a() {
22082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22083         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22084         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22085                 skip "Need MDS version at least 2.11.52"
22086
22087         local MDTIDX=1
22088
22089         test_mkdir $DIR/$tdir
22090         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22091         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22092         [ $mdt_idx -ne 0 ] &&
22093                 error "create local directory on wrong MDT $mdt_idx"
22094
22095         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22096                         error "create remote directory failed"
22097         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22098         [ $mdt_idx -ne $MDTIDX ] &&
22099                 error "create remote directory on wrong MDT $mdt_idx"
22100
22101         createmany -o $DIR/$tdir/test_230/t- 10 ||
22102                 error "create files on remote directory failed"
22103         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22104         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22105         rm -r $DIR/$tdir || error "unlink remote directory failed"
22106 }
22107 run_test 230a "Create remote directory and files under the remote directory"
22108
22109 test_230b() {
22110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22111         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22112         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22113                 skip "Need MDS version at least 2.11.52"
22114
22115         local MDTIDX=1
22116         local mdt_index
22117         local i
22118         local file
22119         local pid
22120         local stripe_count
22121         local migrate_dir=$DIR/$tdir/migrate_dir
22122         local other_dir=$DIR/$tdir/other_dir
22123
22124         test_mkdir $DIR/$tdir
22125         test_mkdir -i0 -c1 $migrate_dir
22126         test_mkdir -i0 -c1 $other_dir
22127         for ((i=0; i<10; i++)); do
22128                 mkdir -p $migrate_dir/dir_${i}
22129                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22130                         error "create files under remote dir failed $i"
22131         done
22132
22133         cp /etc/passwd $migrate_dir/$tfile
22134         cp /etc/passwd $other_dir/$tfile
22135         chattr +SAD $migrate_dir
22136         chattr +SAD $migrate_dir/$tfile
22137
22138         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22139         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22140         local old_dir_mode=$(stat -c%f $migrate_dir)
22141         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22142
22143         mkdir -p $migrate_dir/dir_default_stripe2
22144         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22145         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22146
22147         mkdir -p $other_dir
22148         ln $migrate_dir/$tfile $other_dir/luna
22149         ln $migrate_dir/$tfile $migrate_dir/sofia
22150         ln $other_dir/$tfile $migrate_dir/david
22151         ln -s $migrate_dir/$tfile $other_dir/zachary
22152         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22153         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22154
22155         local len
22156         local lnktgt
22157
22158         # inline symlink
22159         for len in 58 59 60; do
22160                 lnktgt=$(str_repeat 'l' $len)
22161                 touch $migrate_dir/$lnktgt
22162                 ln -s $lnktgt $migrate_dir/${len}char_ln
22163         done
22164
22165         # PATH_MAX
22166         for len in 4094 4095; do
22167                 lnktgt=$(str_repeat 'l' $len)
22168                 ln -s $lnktgt $migrate_dir/${len}char_ln
22169         done
22170
22171         # NAME_MAX
22172         for len in 254 255; do
22173                 touch $migrate_dir/$(str_repeat 'l' $len)
22174         done
22175
22176         $LFS migrate -m $MDTIDX $migrate_dir ||
22177                 error "fails on migrating remote dir to MDT1"
22178
22179         echo "migratate to MDT1, then checking.."
22180         for ((i = 0; i < 10; i++)); do
22181                 for file in $(find $migrate_dir/dir_${i}); do
22182                         mdt_index=$($LFS getstripe -m $file)
22183                         # broken symlink getstripe will fail
22184                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22185                                 error "$file is not on MDT${MDTIDX}"
22186                 done
22187         done
22188
22189         # the multiple link file should still in MDT0
22190         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22191         [ $mdt_index == 0 ] ||
22192                 error "$file is not on MDT${MDTIDX}"
22193
22194         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22195         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22196                 error " expect $old_dir_flag get $new_dir_flag"
22197
22198         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22199         [ "$old_file_flag" = "$new_file_flag" ] ||
22200                 error " expect $old_file_flag get $new_file_flag"
22201
22202         local new_dir_mode=$(stat -c%f $migrate_dir)
22203         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22204                 error "expect mode $old_dir_mode get $new_dir_mode"
22205
22206         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22207         [ "$old_file_mode" = "$new_file_mode" ] ||
22208                 error "expect mode $old_file_mode get $new_file_mode"
22209
22210         diff /etc/passwd $migrate_dir/$tfile ||
22211                 error "$tfile different after migration"
22212
22213         diff /etc/passwd $other_dir/luna ||
22214                 error "luna different after migration"
22215
22216         diff /etc/passwd $migrate_dir/sofia ||
22217                 error "sofia different after migration"
22218
22219         diff /etc/passwd $migrate_dir/david ||
22220                 error "david different after migration"
22221
22222         diff /etc/passwd $other_dir/zachary ||
22223                 error "zachary different after migration"
22224
22225         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22226                 error "${tfile}_ln different after migration"
22227
22228         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22229                 error "${tfile}_ln_other different after migration"
22230
22231         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22232         [ $stripe_count = 2 ] ||
22233                 error "dir strpe_count $d != 2 after migration."
22234
22235         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22236         [ $stripe_count = 2 ] ||
22237                 error "file strpe_count $d != 2 after migration."
22238
22239         #migrate back to MDT0
22240         MDTIDX=0
22241
22242         $LFS migrate -m $MDTIDX $migrate_dir ||
22243                 error "fails on migrating remote dir to MDT0"
22244
22245         echo "migrate back to MDT0, checking.."
22246         for file in $(find $migrate_dir); do
22247                 mdt_index=$($LFS getstripe -m $file)
22248                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22249                         error "$file is not on MDT${MDTIDX}"
22250         done
22251
22252         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22253         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22254                 error " expect $old_dir_flag get $new_dir_flag"
22255
22256         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22257         [ "$old_file_flag" = "$new_file_flag" ] ||
22258                 error " expect $old_file_flag get $new_file_flag"
22259
22260         local new_dir_mode=$(stat -c%f $migrate_dir)
22261         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22262                 error "expect mode $old_dir_mode get $new_dir_mode"
22263
22264         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22265         [ "$old_file_mode" = "$new_file_mode" ] ||
22266                 error "expect mode $old_file_mode get $new_file_mode"
22267
22268         diff /etc/passwd ${migrate_dir}/$tfile ||
22269                 error "$tfile different after migration"
22270
22271         diff /etc/passwd ${other_dir}/luna ||
22272                 error "luna different after migration"
22273
22274         diff /etc/passwd ${migrate_dir}/sofia ||
22275                 error "sofia different after migration"
22276
22277         diff /etc/passwd ${other_dir}/zachary ||
22278                 error "zachary different after migration"
22279
22280         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22281                 error "${tfile}_ln different after migration"
22282
22283         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22284                 error "${tfile}_ln_other different after migration"
22285
22286         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22287         [ $stripe_count = 2 ] ||
22288                 error "dir strpe_count $d != 2 after migration."
22289
22290         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22291         [ $stripe_count = 2 ] ||
22292                 error "file strpe_count $d != 2 after migration."
22293
22294         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22295 }
22296 run_test 230b "migrate directory"
22297
22298 test_230c() {
22299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22301         remote_mds_nodsh && skip "remote MDS with nodsh"
22302         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22303                 skip "Need MDS version at least 2.11.52"
22304
22305         local MDTIDX=1
22306         local total=3
22307         local mdt_index
22308         local file
22309         local migrate_dir=$DIR/$tdir/migrate_dir
22310
22311         #If migrating directory fails in the middle, all entries of
22312         #the directory is still accessiable.
22313         test_mkdir $DIR/$tdir
22314         test_mkdir -i0 -c1 $migrate_dir
22315         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22316         stat $migrate_dir
22317         createmany -o $migrate_dir/f $total ||
22318                 error "create files under ${migrate_dir} failed"
22319
22320         # fail after migrating top dir, and this will fail only once, so the
22321         # first sub file migration will fail (currently f3), others succeed.
22322         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22323         do_facet mds1 lctl set_param fail_loc=0x1801
22324         local t=$(ls $migrate_dir | wc -l)
22325         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22326                 error "migrate should fail"
22327         local u=$(ls $migrate_dir | wc -l)
22328         [ "$u" == "$t" ] || error "$u != $t during migration"
22329
22330         # add new dir/file should succeed
22331         mkdir $migrate_dir/dir ||
22332                 error "mkdir failed under migrating directory"
22333         touch $migrate_dir/file ||
22334                 error "create file failed under migrating directory"
22335
22336         # add file with existing name should fail
22337         for file in $migrate_dir/f*; do
22338                 stat $file > /dev/null || error "stat $file failed"
22339                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22340                         error "open(O_CREAT|O_EXCL) $file should fail"
22341                 $MULTIOP $file m && error "create $file should fail"
22342                 touch $DIR/$tdir/remote_dir/$tfile ||
22343                         error "touch $tfile failed"
22344                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22345                         error "link $file should fail"
22346                 mdt_index=$($LFS getstripe -m $file)
22347                 if [ $mdt_index == 0 ]; then
22348                         # file failed to migrate is not allowed to rename to
22349                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22350                                 error "rename to $file should fail"
22351                 else
22352                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22353                                 error "rename to $file failed"
22354                 fi
22355                 echo hello >> $file || error "write $file failed"
22356         done
22357
22358         # resume migration with different options should fail
22359         $LFS migrate -m 0 $migrate_dir &&
22360                 error "migrate -m 0 $migrate_dir should fail"
22361
22362         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22363                 error "migrate -c 2 $migrate_dir should fail"
22364
22365         # resume migration should succeed
22366         $LFS migrate -m $MDTIDX $migrate_dir ||
22367                 error "migrate $migrate_dir failed"
22368
22369         echo "Finish migration, then checking.."
22370         for file in $(find $migrate_dir); do
22371                 mdt_index=$($LFS getstripe -m $file)
22372                 [ $mdt_index == $MDTIDX ] ||
22373                         error "$file is not on MDT${MDTIDX}"
22374         done
22375
22376         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22377 }
22378 run_test 230c "check directory accessiblity if migration failed"
22379
22380 test_230d() {
22381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22382         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22383         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22384                 skip "Need MDS version at least 2.11.52"
22385         # LU-11235
22386         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22387
22388         local migrate_dir=$DIR/$tdir/migrate_dir
22389         local old_index
22390         local new_index
22391         local old_count
22392         local new_count
22393         local new_hash
22394         local mdt_index
22395         local i
22396         local j
22397
22398         old_index=$((RANDOM % MDSCOUNT))
22399         old_count=$((MDSCOUNT - old_index))
22400         new_index=$((RANDOM % MDSCOUNT))
22401         new_count=$((MDSCOUNT - new_index))
22402         new_hash=1 # for all_char
22403
22404         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22405         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22406
22407         test_mkdir $DIR/$tdir
22408         test_mkdir -i $old_index -c $old_count $migrate_dir
22409
22410         for ((i=0; i<100; i++)); do
22411                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22412                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22413                         error "create files under remote dir failed $i"
22414         done
22415
22416         echo -n "Migrate from MDT$old_index "
22417         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22418         echo -n "to MDT$new_index"
22419         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22420         echo
22421
22422         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22423         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22424                 error "migrate remote dir error"
22425
22426         echo "Finish migration, then checking.."
22427         for file in $(find $migrate_dir -maxdepth 1); do
22428                 mdt_index=$($LFS getstripe -m $file)
22429                 if [ $mdt_index -lt $new_index ] ||
22430                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22431                         error "$file is on MDT$mdt_index"
22432                 fi
22433         done
22434
22435         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22436 }
22437 run_test 230d "check migrate big directory"
22438
22439 test_230e() {
22440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22442         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22443                 skip "Need MDS version at least 2.11.52"
22444
22445         local i
22446         local j
22447         local a_fid
22448         local b_fid
22449
22450         mkdir_on_mdt0 $DIR/$tdir
22451         mkdir $DIR/$tdir/migrate_dir
22452         mkdir $DIR/$tdir/other_dir
22453         touch $DIR/$tdir/migrate_dir/a
22454         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22455         ls $DIR/$tdir/other_dir
22456
22457         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22458                 error "migrate dir fails"
22459
22460         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22461         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22462
22463         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22464         [ $mdt_index == 0 ] || error "a is not on MDT0"
22465
22466         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22467                 error "migrate dir fails"
22468
22469         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22470         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22471
22472         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22473         [ $mdt_index == 1 ] || error "a is not on MDT1"
22474
22475         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22476         [ $mdt_index == 1 ] || error "b is not on MDT1"
22477
22478         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22479         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22480
22481         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22482
22483         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22484 }
22485 run_test 230e "migrate mulitple local link files"
22486
22487 test_230f() {
22488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22489         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22490         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22491                 skip "Need MDS version at least 2.11.52"
22492
22493         local a_fid
22494         local ln_fid
22495
22496         mkdir -p $DIR/$tdir
22497         mkdir $DIR/$tdir/migrate_dir
22498         $LFS mkdir -i1 $DIR/$tdir/other_dir
22499         touch $DIR/$tdir/migrate_dir/a
22500         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22501         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22502         ls $DIR/$tdir/other_dir
22503
22504         # a should be migrated to MDT1, since no other links on MDT0
22505         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22506                 error "#1 migrate dir fails"
22507         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22508         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22509         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22510         [ $mdt_index == 1 ] || error "a is not on MDT1"
22511
22512         # a should stay on MDT1, because it is a mulitple link file
22513         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22514                 error "#2 migrate dir fails"
22515         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22516         [ $mdt_index == 1 ] || error "a is not on MDT1"
22517
22518         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22519                 error "#3 migrate dir fails"
22520
22521         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22522         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22523         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22524
22525         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22526         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22527
22528         # a should be migrated to MDT0, since no other links on MDT1
22529         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22530                 error "#4 migrate dir fails"
22531         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22532         [ $mdt_index == 0 ] || error "a is not on MDT0"
22533
22534         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22535 }
22536 run_test 230f "migrate mulitple remote link files"
22537
22538 test_230g() {
22539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22541         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22542                 skip "Need MDS version at least 2.11.52"
22543
22544         mkdir -p $DIR/$tdir/migrate_dir
22545
22546         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22547                 error "migrating dir to non-exist MDT succeeds"
22548         true
22549 }
22550 run_test 230g "migrate dir to non-exist MDT"
22551
22552 test_230h() {
22553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22555         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22556                 skip "Need MDS version at least 2.11.52"
22557
22558         local mdt_index
22559
22560         mkdir -p $DIR/$tdir/migrate_dir
22561
22562         $LFS migrate -m1 $DIR &&
22563                 error "migrating mountpoint1 should fail"
22564
22565         $LFS migrate -m1 $DIR/$tdir/.. &&
22566                 error "migrating mountpoint2 should fail"
22567
22568         # same as mv
22569         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22570                 error "migrating $tdir/migrate_dir/.. should fail"
22571
22572         true
22573 }
22574 run_test 230h "migrate .. and root"
22575
22576 test_230i() {
22577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22579         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22580                 skip "Need MDS version at least 2.11.52"
22581
22582         mkdir -p $DIR/$tdir/migrate_dir
22583
22584         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22585                 error "migration fails with a tailing slash"
22586
22587         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22588                 error "migration fails with two tailing slashes"
22589 }
22590 run_test 230i "lfs migrate -m tolerates trailing slashes"
22591
22592 test_230j() {
22593         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22594         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22595                 skip "Need MDS version at least 2.11.52"
22596
22597         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22598         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22599                 error "create $tfile failed"
22600         cat /etc/passwd > $DIR/$tdir/$tfile
22601
22602         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22603
22604         cmp /etc/passwd $DIR/$tdir/$tfile ||
22605                 error "DoM file mismatch after migration"
22606 }
22607 run_test 230j "DoM file data not changed after dir migration"
22608
22609 test_230k() {
22610         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22611         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22612                 skip "Need MDS version at least 2.11.56"
22613
22614         local total=20
22615         local files_on_starting_mdt=0
22616
22617         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22618         $LFS getdirstripe $DIR/$tdir
22619         for i in $(seq $total); do
22620                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22621                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22622                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22623         done
22624
22625         echo "$files_on_starting_mdt files on MDT0"
22626
22627         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22628         $LFS getdirstripe $DIR/$tdir
22629
22630         files_on_starting_mdt=0
22631         for i in $(seq $total); do
22632                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22633                         error "file $tfile.$i mismatch after migration"
22634                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22635                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22636         done
22637
22638         echo "$files_on_starting_mdt files on MDT1 after migration"
22639         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22640
22641         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22642         $LFS getdirstripe $DIR/$tdir
22643
22644         files_on_starting_mdt=0
22645         for i in $(seq $total); do
22646                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22647                         error "file $tfile.$i mismatch after 2nd migration"
22648                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22649                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22650         done
22651
22652         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22653         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22654
22655         true
22656 }
22657 run_test 230k "file data not changed after dir migration"
22658
22659 test_230l() {
22660         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22661         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22662                 skip "Need MDS version at least 2.11.56"
22663
22664         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22665         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22666                 error "create files under remote dir failed $i"
22667         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22668 }
22669 run_test 230l "readdir between MDTs won't crash"
22670
22671 test_230m() {
22672         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22673         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22674                 skip "Need MDS version at least 2.11.56"
22675
22676         local MDTIDX=1
22677         local mig_dir=$DIR/$tdir/migrate_dir
22678         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22679         local shortstr="b"
22680         local val
22681
22682         echo "Creating files and dirs with xattrs"
22683         test_mkdir $DIR/$tdir
22684         test_mkdir -i0 -c1 $mig_dir
22685         mkdir $mig_dir/dir
22686         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22687                 error "cannot set xattr attr1 on dir"
22688         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22689                 error "cannot set xattr attr2 on dir"
22690         touch $mig_dir/dir/f0
22691         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22692                 error "cannot set xattr attr1 on file"
22693         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22694                 error "cannot set xattr attr2 on file"
22695         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22696         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22697         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22698         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22699         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22700         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22701         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22702         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22703         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22704
22705         echo "Migrating to MDT1"
22706         $LFS migrate -m $MDTIDX $mig_dir ||
22707                 error "fails on migrating dir to MDT1"
22708
22709         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22710         echo "Checking xattrs"
22711         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22712         [ "$val" = $longstr ] ||
22713                 error "expecting xattr1 $longstr on dir, found $val"
22714         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22715         [ "$val" = $shortstr ] ||
22716                 error "expecting xattr2 $shortstr on dir, found $val"
22717         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22718         [ "$val" = $longstr ] ||
22719                 error "expecting xattr1 $longstr on file, found $val"
22720         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22721         [ "$val" = $shortstr ] ||
22722                 error "expecting xattr2 $shortstr on file, found $val"
22723 }
22724 run_test 230m "xattrs not changed after dir migration"
22725
22726 test_230n() {
22727         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22728         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22729                 skip "Need MDS version at least 2.13.53"
22730
22731         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22732         cat /etc/hosts > $DIR/$tdir/$tfile
22733         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22734         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22735
22736         cmp /etc/hosts $DIR/$tdir/$tfile ||
22737                 error "File data mismatch after migration"
22738 }
22739 run_test 230n "Dir migration with mirrored file"
22740
22741 test_230o() {
22742         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22743         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22744                 skip "Need MDS version at least 2.13.52"
22745
22746         local mdts=$(comma_list $(mdts_nodes))
22747         local timeout=100
22748         local restripe_status
22749         local delta
22750         local i
22751
22752         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22753
22754         # in case "crush" hash type is not set
22755         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22756
22757         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22758                            mdt.*MDT0000.enable_dir_restripe)
22759         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22760         stack_trap "do_nodes $mdts $LCTL set_param \
22761                     mdt.*.enable_dir_restripe=$restripe_status"
22762
22763         mkdir $DIR/$tdir
22764         createmany -m $DIR/$tdir/f 100 ||
22765                 error "create files under remote dir failed $i"
22766         createmany -d $DIR/$tdir/d 100 ||
22767                 error "create dirs under remote dir failed $i"
22768
22769         for i in $(seq 2 $MDSCOUNT); do
22770                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22771                 $LFS setdirstripe -c $i $DIR/$tdir ||
22772                         error "split -c $i $tdir failed"
22773                 wait_update $HOSTNAME \
22774                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22775                         error "dir split not finished"
22776                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22777                         awk '/migrate/ {sum += $2} END { print sum }')
22778                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22779                 # delta is around total_files/stripe_count
22780                 (( $delta < 200 / (i - 1) + 4 )) ||
22781                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22782         done
22783 }
22784 run_test 230o "dir split"
22785
22786 test_230p() {
22787         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22788         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22789                 skip "Need MDS version at least 2.13.52"
22790
22791         local mdts=$(comma_list $(mdts_nodes))
22792         local timeout=100
22793         local restripe_status
22794         local delta
22795         local c
22796
22797         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22798
22799         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22800
22801         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22802                            mdt.*MDT0000.enable_dir_restripe)
22803         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22804         stack_trap "do_nodes $mdts $LCTL set_param \
22805                     mdt.*.enable_dir_restripe=$restripe_status"
22806
22807         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22808         createmany -m $DIR/$tdir/f 100 ||
22809                 error "create files under remote dir failed"
22810         createmany -d $DIR/$tdir/d 100 ||
22811                 error "create dirs under remote dir failed"
22812
22813         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22814                 local mdt_hash="crush"
22815
22816                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22817                 $LFS setdirstripe -c $c $DIR/$tdir ||
22818                         error "split -c $c $tdir failed"
22819                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22820                         mdt_hash="$mdt_hash,fixed"
22821                 elif [ $c -eq 1 ]; then
22822                         mdt_hash="none"
22823                 fi
22824                 wait_update $HOSTNAME \
22825                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22826                         error "dir merge not finished"
22827                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22828                         awk '/migrate/ {sum += $2} END { print sum }')
22829                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22830                 # delta is around total_files/stripe_count
22831                 (( delta < 200 / c + 4 )) ||
22832                         error "$delta files migrated >= $((200 / c + 4))"
22833         done
22834 }
22835 run_test 230p "dir merge"
22836
22837 test_230q() {
22838         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22839         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22840                 skip "Need MDS version at least 2.13.52"
22841
22842         local mdts=$(comma_list $(mdts_nodes))
22843         local saved_threshold=$(do_facet mds1 \
22844                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22845         local saved_delta=$(do_facet mds1 \
22846                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22847         local threshold=100
22848         local delta=2
22849         local total=0
22850         local stripe_count=0
22851         local stripe_index
22852         local nr_files
22853         local create
22854
22855         # test with fewer files on ZFS
22856         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22857
22858         stack_trap "do_nodes $mdts $LCTL set_param \
22859                     mdt.*.dir_split_count=$saved_threshold"
22860         stack_trap "do_nodes $mdts $LCTL set_param \
22861                     mdt.*.dir_split_delta=$saved_delta"
22862         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22863         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22864         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22865         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22866         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22867         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22868
22869         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22870         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22871
22872         create=$((threshold * 3 / 2))
22873         while [ $stripe_count -lt $MDSCOUNT ]; do
22874                 createmany -m $DIR/$tdir/f $total $create ||
22875                         error "create sub files failed"
22876                 stat $DIR/$tdir > /dev/null
22877                 total=$((total + create))
22878                 stripe_count=$((stripe_count + delta))
22879                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22880
22881                 wait_update $HOSTNAME \
22882                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22883                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22884
22885                 wait_update $HOSTNAME \
22886                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22887                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22888
22889                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22890                 echo "$nr_files/$total files on MDT$stripe_index after split"
22891                 # allow 10% margin of imbalance with crush hash
22892                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22893                         error "$nr_files files on MDT$stripe_index after split"
22894
22895                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22896                 [ $nr_files -eq $total ] ||
22897                         error "total sub files $nr_files != $total"
22898         done
22899
22900         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22901
22902         echo "fixed layout directory won't auto split"
22903         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22904         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22905                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22906         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22907                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22908 }
22909 run_test 230q "dir auto split"
22910
22911 test_230r() {
22912         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22913         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22914         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22915                 skip "Need MDS version at least 2.13.54"
22916
22917         # maximum amount of local locks:
22918         # parent striped dir - 2 locks
22919         # new stripe in parent to migrate to - 1 lock
22920         # source and target - 2 locks
22921         # Total 5 locks for regular file
22922         mkdir -p $DIR/$tdir
22923         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22924         touch $DIR/$tdir/dir1/eee
22925
22926         # create 4 hardlink for 4 more locks
22927         # Total: 9 locks > RS_MAX_LOCKS (8)
22928         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22929         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22930         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22931         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22932         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22933         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22934         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22935         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22936
22937         cancel_lru_locks mdc
22938
22939         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22940                 error "migrate dir fails"
22941
22942         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22943 }
22944 run_test 230r "migrate with too many local locks"
22945
22946 test_230s() {
22947         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22948                 skip "Need MDS version at least 2.14.52"
22949
22950         local mdts=$(comma_list $(mdts_nodes))
22951         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22952                                 mdt.*MDT0000.enable_dir_restripe)
22953
22954         stack_trap "do_nodes $mdts $LCTL set_param \
22955                     mdt.*.enable_dir_restripe=$restripe_status"
22956
22957         local st
22958         for st in 0 1; do
22959                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22960                 test_mkdir $DIR/$tdir
22961                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22962                         error "$LFS mkdir should return EEXIST if target exists"
22963                 rmdir $DIR/$tdir
22964         done
22965 }
22966 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22967
22968 test_230t()
22969 {
22970         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22971         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22972                 skip "Need MDS version at least 2.14.50"
22973
22974         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22975         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22976         $LFS project -p 1 -s $DIR/$tdir ||
22977                 error "set $tdir project id failed"
22978         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22979                 error "set subdir project id failed"
22980         local pbefore="$($LFS project -d $DIR/$tdir)"
22981         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22982         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22983
22984         local pafter="$($LFS project -d $DIR/$tdir)"
22985         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22986         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22987         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22988
22989         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22990                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22991
22992         # check rename works, even if source parent projid differs (LU-17016)
22993         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22994         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22995
22996         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22997         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22998                 error "subdir failed rename for different source parent projid"
22999         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
23000
23001         [[ "$fid_before" == "$fid_after" ]] ||
23002                 error "fid before '$fid_before' != after '$fid_after'"
23003 }
23004 run_test 230t "migrate directory with project ID set"
23005
23006 test_230u()
23007 {
23008         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23009         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23010                 skip "Need MDS version at least 2.14.53"
23011
23012         local count
23013
23014         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23015         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23016         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
23017         for i in $(seq 0 $((MDSCOUNT - 1))); do
23018                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23019                 echo "$count dirs migrated to MDT$i"
23020         done
23021         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23022         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
23023 }
23024 run_test 230u "migrate directory by QOS"
23025
23026 test_230v()
23027 {
23028         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
23029         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
23030                 skip "Need MDS version at least 2.14.53"
23031
23032         local count
23033
23034         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23035         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23036         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23037         for i in $(seq 0 $((MDSCOUNT - 1))); do
23038                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23039                 echo "$count subdirs migrated to MDT$i"
23040                 (( i == 3 )) && (( count > 0 )) &&
23041                         error "subdir shouldn't be migrated to MDT3"
23042         done
23043         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23044         (( count == 3 )) || error "dirs migrated to $count MDTs"
23045 }
23046 run_test 230v "subdir migrated to the MDT where its parent is located"
23047
23048 test_230w() {
23049         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23050         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23051                 skip "Need MDS version at least 2.15.0"
23052
23053         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23054         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23055         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23056
23057         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23058                 error "migrate failed"
23059
23060         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23061                 error "$tdir stripe count mismatch"
23062
23063         for i in $(seq 0 9); do
23064                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23065                         error "d$i is striped"
23066         done
23067 }
23068 run_test 230w "non-recursive mode dir migration"
23069
23070 test_230x() {
23071         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23072         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23073                 skip "Need MDS version at least 2.15.0"
23074
23075         mkdir -p $DIR/$tdir || error "mkdir failed"
23076         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23077
23078         local mdt_name=$(mdtname_from_index 0)
23079         local low=$(do_facet mds2 $LCTL get_param -n \
23080                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23081         local high=$(do_facet mds2 $LCTL get_param -n \
23082                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23083         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23084         local maxage=$(do_facet mds2 $LCTL get_param -n \
23085                 osp.*$mdt_name-osp-MDT0001.maxage)
23086
23087         stack_trap "do_facet mds2 $LCTL set_param -n \
23088                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23089                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23090         stack_trap "do_facet mds2 $LCTL set_param -n \
23091                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23092
23093         do_facet mds2 $LCTL set_param -n \
23094                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23095         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23096         sleep 4
23097         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23098                 error "migrate $tdir should fail"
23099
23100         do_facet mds2 $LCTL set_param -n \
23101                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23102         do_facet mds2 $LCTL set_param -n \
23103                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23104         sleep 4
23105         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23106                 error "migrate failed"
23107         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23108                 error "$tdir stripe count mismatch"
23109 }
23110 run_test 230x "dir migration check space"
23111
23112 test_230y() {
23113         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23114         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23115                 skip "Need MDS version at least 2.15.55.45"
23116
23117         local pid
23118
23119         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23120         $LFS getdirstripe $DIR/$tdir
23121         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23122         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23123         pid=$!
23124         sleep 1
23125
23126         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23127         do_facet mds2 lctl set_param fail_loc=0x1802
23128
23129         wait $pid
23130         do_facet mds2 lctl set_param fail_loc=0
23131         $LFS getdirstripe $DIR/$tdir
23132         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23133         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23134 }
23135 run_test 230y "unlink dir with bad hash type"
23136
23137 test_230z() {
23138         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23139         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23140                 skip "Need MDS version at least 2.15.55.45"
23141
23142         local pid
23143
23144         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23145         $LFS getdirstripe $DIR/$tdir
23146         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23147         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23148         pid=$!
23149         sleep 1
23150
23151         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23152         do_facet mds2 lctl set_param fail_loc=0x1802
23153
23154         wait $pid
23155         do_facet mds2 lctl set_param fail_loc=0
23156         $LFS getdirstripe $DIR/$tdir
23157
23158         # resume migration
23159         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23160                 error "resume migration failed"
23161         $LFS getdirstripe $DIR/$tdir
23162         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23163                 error "migration is not finished"
23164 }
23165 run_test 230z "resume dir migration with bad hash type"
23166
23167 test_231a()
23168 {
23169         # For simplicity this test assumes that max_pages_per_rpc
23170         # is the same across all OSCs
23171         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23172         local bulk_size=$((max_pages * PAGE_SIZE))
23173         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23174                                        head -n 1)
23175
23176         mkdir -p $DIR/$tdir
23177         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23178                 error "failed to set stripe with -S ${brw_size}M option"
23179         stack_trap "rm -rf $DIR/$tdir"
23180
23181         # clear the OSC stats
23182         $LCTL set_param osc.*.stats=0 &>/dev/null
23183         stop_writeback
23184
23185         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23186         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23187                 oflag=direct &>/dev/null || error "dd failed"
23188
23189         sync; sleep 1; sync # just to be safe
23190         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23191         if [ x$nrpcs != "x1" ]; then
23192                 $LCTL get_param osc.*.stats
23193                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23194         fi
23195
23196         start_writeback
23197         # Drop the OSC cache, otherwise we will read from it
23198         cancel_lru_locks osc
23199
23200         # clear the OSC stats
23201         $LCTL set_param osc.*.stats=0 &>/dev/null
23202
23203         # Client reads $bulk_size.
23204         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23205                 iflag=direct &>/dev/null || error "dd failed"
23206
23207         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23208         if [ x$nrpcs != "x1" ]; then
23209                 $LCTL get_param osc.*.stats
23210                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23211         fi
23212 }
23213 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23214
23215 test_231b() {
23216         mkdir -p $DIR/$tdir
23217         stack_trap "rm -rf $DIR/$tdir"
23218         local i
23219         for i in {0..1023}; do
23220                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23221                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23222                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23223         done
23224         sync
23225 }
23226 run_test 231b "must not assert on fully utilized OST request buffer"
23227
23228 test_232a() {
23229         mkdir -p $DIR/$tdir
23230         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23231
23232         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23233         do_facet ost1 $LCTL set_param fail_loc=0x31c
23234
23235         # ignore dd failure
23236         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23237         stack_trap "rm -f $DIR/$tdir/$tfile"
23238
23239         do_facet ost1 $LCTL set_param fail_loc=0
23240         umount_client $MOUNT || error "umount failed"
23241         mount_client $MOUNT || error "mount failed"
23242         stop ost1 || error "cannot stop ost1"
23243         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23244 }
23245 run_test 232a "failed lock should not block umount"
23246
23247 test_232b() {
23248         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23249                 skip "Need MDS version at least 2.10.58"
23250
23251         mkdir -p $DIR/$tdir
23252         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23253         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23254         stack_trap "rm -f $DIR/$tdir/$tfile"
23255         sync
23256         cancel_lru_locks osc
23257
23258         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23259         do_facet ost1 $LCTL set_param fail_loc=0x31c
23260
23261         # ignore failure
23262         $LFS data_version $DIR/$tdir/$tfile || true
23263
23264         do_facet ost1 $LCTL set_param fail_loc=0
23265         umount_client $MOUNT || error "umount failed"
23266         mount_client $MOUNT || error "mount failed"
23267         stop ost1 || error "cannot stop ost1"
23268         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23269 }
23270 run_test 232b "failed data version lock should not block umount"
23271
23272 test_233a() {
23273         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23274                 skip "Need MDS version at least 2.3.64"
23275         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23276
23277         local fid=$($LFS path2fid $MOUNT)
23278
23279         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23280                 error "cannot access $MOUNT using its FID '$fid'"
23281 }
23282 run_test 233a "checking that OBF of the FS root succeeds"
23283
23284 test_233b() {
23285         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23286                 skip "Need MDS version at least 2.5.90"
23287         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23288
23289         local fid=$($LFS path2fid $MOUNT/.lustre)
23290
23291         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23292                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23293
23294         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23295         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23296                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23297 }
23298 run_test 233b "checking that OBF of the FS .lustre succeeds"
23299
23300 test_234() {
23301         local p="$TMP/sanityN-$TESTNAME.parameters"
23302         save_lustre_params client "llite.*.xattr_cache" > $p
23303         lctl set_param llite.*.xattr_cache 1 ||
23304                 skip_env "xattr cache is not supported"
23305
23306         mkdir -p $DIR/$tdir || error "mkdir failed"
23307         touch $DIR/$tdir/$tfile || error "touch failed"
23308         # OBD_FAIL_LLITE_XATTR_ENOMEM
23309         $LCTL set_param fail_loc=0x1405
23310         getfattr -n user.attr $DIR/$tdir/$tfile &&
23311                 error "getfattr should have failed with ENOMEM"
23312         $LCTL set_param fail_loc=0x0
23313         rm -rf $DIR/$tdir
23314
23315         restore_lustre_params < $p
23316         rm -f $p
23317 }
23318 run_test 234 "xattr cache should not crash on ENOMEM"
23319
23320 test_235() {
23321         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23322                 skip "Need MDS version at least 2.4.52"
23323
23324         flock_deadlock $DIR/$tfile
23325         local RC=$?
23326         case $RC in
23327                 0)
23328                 ;;
23329                 124) error "process hangs on a deadlock"
23330                 ;;
23331                 *) error "error executing flock_deadlock $DIR/$tfile"
23332                 ;;
23333         esac
23334 }
23335 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23336
23337 #LU-2935
23338 test_236() {
23339         check_swap_layouts_support
23340
23341         local ref1=/etc/passwd
23342         local ref2=/etc/group
23343         local file1=$DIR/$tdir/f1
23344         local file2=$DIR/$tdir/f2
23345
23346         test_mkdir -c1 $DIR/$tdir
23347         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23348         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23349         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23350         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23351         local fd=$(free_fd)
23352         local cmd="exec $fd<>$file2"
23353         eval $cmd
23354         rm $file2
23355         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23356                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23357         cmd="exec $fd>&-"
23358         eval $cmd
23359         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23360
23361         #cleanup
23362         rm -rf $DIR/$tdir
23363 }
23364 run_test 236 "Layout swap on open unlinked file"
23365
23366 # LU-4659 linkea consistency
23367 test_238() {
23368         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23369                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23370                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23371                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23372
23373         touch $DIR/$tfile
23374         ln $DIR/$tfile $DIR/$tfile.lnk
23375         touch $DIR/$tfile.new
23376         mv $DIR/$tfile.new $DIR/$tfile
23377         local fid1=$($LFS path2fid $DIR/$tfile)
23378         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23379         local path1=$($LFS fid2path $FSNAME "$fid1")
23380         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23381         local path2=$($LFS fid2path $FSNAME "$fid2")
23382         [ $tfile.lnk == $path2 ] ||
23383                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23384         rm -f $DIR/$tfile*
23385 }
23386 run_test 238 "Verify linkea consistency"
23387
23388 test_239A() { # was test_239
23389         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23390                 skip "Need MDS version at least 2.5.60"
23391
23392         local list=$(comma_list $(mdts_nodes))
23393
23394         mkdir -p $DIR/$tdir
23395         createmany -o $DIR/$tdir/f- 5000
23396         unlinkmany $DIR/$tdir/f- 5000
23397         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23398                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23399         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23400                         osp.*MDT*.sync_in_flight" | calc_sum)
23401         [ "$changes" -eq 0 ] || error "$changes not synced"
23402 }
23403 run_test 239A "osp_sync test"
23404
23405 test_239a() { #LU-5297
23406         remote_mds_nodsh && skip "remote MDS with nodsh"
23407
23408         touch $DIR/$tfile
23409         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23410         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23411         chgrp $RUNAS_GID $DIR/$tfile
23412         wait_delete_completed
23413 }
23414 run_test 239a "process invalid osp sync record correctly"
23415
23416 test_239b() { #LU-5297
23417         remote_mds_nodsh && skip "remote MDS with nodsh"
23418
23419         touch $DIR/$tfile1
23420         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23421         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23422         chgrp $RUNAS_GID $DIR/$tfile1
23423         wait_delete_completed
23424         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23425         touch $DIR/$tfile2
23426         chgrp $RUNAS_GID $DIR/$tfile2
23427         wait_delete_completed
23428 }
23429 run_test 239b "process osp sync record with ENOMEM error correctly"
23430
23431 test_240() {
23432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23433         remote_mds_nodsh && skip "remote MDS with nodsh"
23434
23435         mkdir -p $DIR/$tdir
23436
23437         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23438                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23439         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23440                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23441
23442         umount_client $MOUNT || error "umount failed"
23443         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23444         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23445         mount_client $MOUNT || error "failed to mount client"
23446
23447         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23448         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23449 }
23450 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23451
23452 test_241_bio() {
23453         local count=$1
23454         local bsize=$2
23455
23456         for LOOP in $(seq $count); do
23457                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23458                 cancel_lru_locks $OSC || true
23459         done
23460 }
23461
23462 test_241_dio() {
23463         local count=$1
23464         local bsize=$2
23465
23466         for LOOP in $(seq $1); do
23467                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23468                         2>/dev/null
23469         done
23470 }
23471
23472 test_241a() { # was test_241
23473         local bsize=$PAGE_SIZE
23474
23475         (( bsize < 40960 )) && bsize=40960
23476         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23477         ls -la $DIR/$tfile
23478         cancel_lru_locks $OSC
23479         test_241_bio 1000 $bsize &
23480         PID=$!
23481         test_241_dio 1000 $bsize
23482         wait $PID
23483 }
23484 run_test 241a "bio vs dio"
23485
23486 test_241b() {
23487         local bsize=$PAGE_SIZE
23488
23489         (( bsize < 40960 )) && bsize=40960
23490         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23491         ls -la $DIR/$tfile
23492         test_241_dio 1000 $bsize &
23493         PID=$!
23494         test_241_dio 1000 $bsize
23495         wait $PID
23496 }
23497 run_test 241b "dio vs dio"
23498
23499 test_242() {
23500         remote_mds_nodsh && skip "remote MDS with nodsh"
23501
23502         mkdir_on_mdt0 $DIR/$tdir
23503         touch $DIR/$tdir/$tfile
23504
23505         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23506         do_facet mds1 lctl set_param fail_loc=0x105
23507         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23508
23509         do_facet mds1 lctl set_param fail_loc=0
23510         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23511 }
23512 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23513
23514 test_243()
23515 {
23516         test_mkdir $DIR/$tdir
23517         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23518 }
23519 run_test 243 "various group lock tests"
23520
23521 test_244a()
23522 {
23523         test_mkdir $DIR/$tdir
23524         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23525         sendfile_grouplock $DIR/$tdir/$tfile || \
23526                 error "sendfile+grouplock failed"
23527         rm -rf $DIR/$tdir
23528 }
23529 run_test 244a "sendfile with group lock tests"
23530
23531 test_244b()
23532 {
23533         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23534
23535         local threads=50
23536         local size=$((1024*1024))
23537
23538         test_mkdir $DIR/$tdir
23539         for i in $(seq 1 $threads); do
23540                 local file=$DIR/$tdir/file_$((i / 10))
23541                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23542                 local pids[$i]=$!
23543         done
23544         for i in $(seq 1 $threads); do
23545                 wait ${pids[$i]}
23546         done
23547 }
23548 run_test 244b "multi-threaded write with group lock"
23549
23550 test_245a() {
23551         local flagname="multi_mod_rpcs"
23552         local connect_data_name="max_mod_rpcs"
23553         local out
23554
23555         # check if multiple modify RPCs flag is set
23556         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23557                 grep "connect_flags:")
23558         echo "$out"
23559
23560         echo "$out" | grep -qw $flagname
23561         if [ $? -ne 0 ]; then
23562                 echo "connect flag $flagname is not set"
23563                 return
23564         fi
23565
23566         # check if multiple modify RPCs data is set
23567         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23568         echo "$out"
23569
23570         echo "$out" | grep -qw $connect_data_name ||
23571                 error "import should have connect data $connect_data_name"
23572 }
23573 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23574
23575 test_245b() {
23576         local flagname="multi_mod_rpcs"
23577         local connect_data_name="max_mod_rpcs"
23578         local out
23579
23580         remote_mds_nodsh && skip "remote MDS with nodsh"
23581         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23582
23583         # check if multiple modify RPCs flag is set
23584         out=$(do_facet mds1 \
23585               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23586               grep "connect_flags:")
23587         echo "$out"
23588
23589         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23590
23591         # check if multiple modify RPCs data is set
23592         out=$(do_facet mds1 \
23593               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23594
23595         [[ "$out" =~ $connect_data_name ]] ||
23596                 {
23597                         echo "$out"
23598                         error "missing connect data $connect_data_name"
23599                 }
23600 }
23601 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23602
23603 cleanup_247() {
23604         local submount=$1
23605
23606         trap 0
23607         umount_client $submount
23608         rmdir $submount
23609 }
23610
23611 test_247a() {
23612         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23613                 grep -q subtree ||
23614                 skip_env "Fileset feature is not supported"
23615
23616         local submount=${MOUNT}_$tdir
23617
23618         mkdir $MOUNT/$tdir
23619         mkdir -p $submount || error "mkdir $submount failed"
23620         FILESET="$FILESET/$tdir" mount_client $submount ||
23621                 error "mount $submount failed"
23622         trap "cleanup_247 $submount" EXIT
23623         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23624         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23625                 error "read $MOUNT/$tdir/$tfile failed"
23626         cleanup_247 $submount
23627 }
23628 run_test 247a "mount subdir as fileset"
23629
23630 test_247b() {
23631         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23632                 skip_env "Fileset feature is not supported"
23633
23634         local submount=${MOUNT}_$tdir
23635
23636         rm -rf $MOUNT/$tdir
23637         mkdir -p $submount || error "mkdir $submount failed"
23638         SKIP_FILESET=1
23639         FILESET="$FILESET/$tdir" mount_client $submount &&
23640                 error "mount $submount should fail"
23641         rmdir $submount
23642 }
23643 run_test 247b "mount subdir that dose not exist"
23644
23645 test_247c() {
23646         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23647                 skip_env "Fileset feature is not supported"
23648
23649         local submount=${MOUNT}_$tdir
23650
23651         mkdir -p $MOUNT/$tdir/dir1
23652         mkdir -p $submount || error "mkdir $submount failed"
23653         trap "cleanup_247 $submount" EXIT
23654         FILESET="$FILESET/$tdir" mount_client $submount ||
23655                 error "mount $submount failed"
23656         local fid=$($LFS path2fid $MOUNT/)
23657         $LFS fid2path $submount $fid && error "fid2path should fail"
23658         cleanup_247 $submount
23659 }
23660 run_test 247c "running fid2path outside subdirectory root"
23661
23662 test_247d() {
23663         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23664                 skip "Fileset feature is not supported"
23665
23666         local submount=${MOUNT}_$tdir
23667
23668         mkdir -p $MOUNT/$tdir/dir1
23669         mkdir -p $submount || error "mkdir $submount failed"
23670         FILESET="$FILESET/$tdir" mount_client $submount ||
23671                 error "mount $submount failed"
23672         trap "cleanup_247 $submount" EXIT
23673
23674         local td=$submount/dir1
23675         local fid=$($LFS path2fid $td)
23676         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23677
23678         # check that we get the same pathname back
23679         local rootpath
23680         local found
23681         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23682                 echo "$rootpath $fid"
23683                 found=$($LFS fid2path $rootpath "$fid")
23684                 [ -n "$found" ] || error "fid2path should succeed"
23685                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23686         done
23687         # check wrong root path format
23688         rootpath=$submount"_wrong"
23689         found=$($LFS fid2path $rootpath "$fid")
23690         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23691
23692         cleanup_247 $submount
23693 }
23694 run_test 247d "running fid2path inside subdirectory root"
23695
23696 # LU-8037
23697 test_247e() {
23698         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23699                 grep -q subtree ||
23700                 skip "Fileset feature is not supported"
23701
23702         local submount=${MOUNT}_$tdir
23703
23704         mkdir $MOUNT/$tdir
23705         mkdir -p $submount || error "mkdir $submount failed"
23706         FILESET="$FILESET/.." mount_client $submount &&
23707                 error "mount $submount should fail"
23708         rmdir $submount
23709 }
23710 run_test 247e "mount .. as fileset"
23711
23712 test_247f() {
23713         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23714         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23715                 skip "Need at least version 2.14.50.162"
23716         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23717                 skip "Fileset feature is not supported"
23718
23719         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23720         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23721                 error "mkdir remote failed"
23722         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23723                 error "mkdir remote/subdir failed"
23724         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23725                 error "mkdir striped failed"
23726         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23727
23728         local submount=${MOUNT}_$tdir
23729
23730         mkdir -p $submount || error "mkdir $submount failed"
23731         stack_trap "rmdir $submount"
23732
23733         local dir
23734         local fileset=$FILESET
23735         local mdts=$(comma_list $(mdts_nodes))
23736
23737         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23738         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23739                 $tdir/striped/subdir $tdir/striped/.; do
23740                 FILESET="$fileset/$dir" mount_client $submount ||
23741                         error "mount $dir failed"
23742                 umount_client $submount
23743         done
23744 }
23745 run_test 247f "mount striped or remote directory as fileset"
23746
23747 test_subdir_mount_lock()
23748 {
23749         local testdir=$1
23750         local submount=${MOUNT}_$(basename $testdir)
23751
23752         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23753
23754         mkdir -p $submount || error "mkdir $submount failed"
23755         stack_trap "rmdir $submount"
23756
23757         FILESET="$fileset/$testdir" mount_client $submount ||
23758                 error "mount $FILESET failed"
23759         stack_trap "umount $submount"
23760
23761         local mdts=$(comma_list $(mdts_nodes))
23762
23763         local nrpcs
23764
23765         stat $submount > /dev/null || error "stat $submount failed"
23766         cancel_lru_locks $MDC
23767         stat $submount > /dev/null || error "stat $submount failed"
23768         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23769         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23770         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23771         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23772                 awk '/getattr/ {sum += $2} END {print sum}')
23773
23774         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23775 }
23776
23777 test_247g() {
23778         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23779
23780         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23781                 error "mkdir $tdir failed"
23782         test_subdir_mount_lock $tdir
23783 }
23784 run_test 247g "striped directory submount revalidate ROOT from cache"
23785
23786 test_247h() {
23787         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23788         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23789                 skip "Need MDS version at least 2.15.51"
23790
23791         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23792         test_subdir_mount_lock $tdir
23793         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23794         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23795                 error "mkdir $tdir.1 failed"
23796         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23797 }
23798 run_test 247h "remote directory submount revalidate ROOT from cache"
23799
23800 test_248a() {
23801         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23802         [ -z "$fast_read_sav" ] && skip "no fast read support"
23803
23804         # create a large file for fast read verification
23805         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23806
23807         # make sure the file is created correctly
23808         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23809                 { rm -f $DIR/$tfile; skip "file creation error"; }
23810
23811         echo "Test 1: verify that fast read is 4 times faster on cache read"
23812
23813         # small read with fast read enabled
23814         $LCTL set_param -n llite.*.fast_read=1
23815         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23816                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23817                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23818         # small read with fast read disabled
23819         $LCTL set_param -n llite.*.fast_read=0
23820         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23821                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23822                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23823
23824         # verify that fast read is 4 times faster for cache read
23825         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23826                 error_not_in_vm "fast read was not 4 times faster: " \
23827                            "$t_fast vs $t_slow"
23828
23829         echo "Test 2: verify the performance between big and small read"
23830         $LCTL set_param -n llite.*.fast_read=1
23831
23832         # 1k non-cache read
23833         cancel_lru_locks osc
23834         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23835                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23836                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23837
23838         # 1M non-cache read
23839         cancel_lru_locks osc
23840         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23841                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23842                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23843
23844         # verify that big IO is not 4 times faster than small IO
23845         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23846                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23847
23848         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23849         rm -f $DIR/$tfile
23850 }
23851 run_test 248a "fast read verification"
23852
23853 test_248b() {
23854         # Default short_io_bytes=16384, try both smaller and larger sizes.
23855         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23856         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23857         echo "bs=53248 count=113 normal buffered write"
23858         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23859                 error "dd of initial data file failed"
23860         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23861
23862         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23863         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23864                 error "dd with sync normal writes failed"
23865         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23866
23867         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23868         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23869                 error "dd with sync small writes failed"
23870         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23871
23872         cancel_lru_locks osc
23873
23874         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23875         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23876         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23877         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23878                 iflag=direct || error "dd with O_DIRECT small read failed"
23879         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23880         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23881                 error "compare $TMP/$tfile.1 failed"
23882
23883         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23884         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23885
23886         # just to see what the maximum tunable value is, and test parsing
23887         echo "test invalid parameter 2MB"
23888         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23889                 error "too-large short_io_bytes allowed"
23890         echo "test maximum parameter 512KB"
23891         # if we can set a larger short_io_bytes, run test regardless of version
23892         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23893                 # older clients may not allow setting it this large, that's OK
23894                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23895                         skip "Need at least client version 2.13.50"
23896                 error "medium short_io_bytes failed"
23897         fi
23898         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23899         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23900
23901         echo "test large parameter 64KB"
23902         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23903         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23904
23905         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23906         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23907                 error "dd with sync large writes failed"
23908         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23909
23910         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23911         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23912         num=$((113 * 4096 / PAGE_SIZE))
23913         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23914         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23915                 error "dd with O_DIRECT large writes failed"
23916         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23917                 error "compare $DIR/$tfile.3 failed"
23918
23919         cancel_lru_locks osc
23920
23921         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23922         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23923                 error "dd with O_DIRECT large read failed"
23924         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23925                 error "compare $TMP/$tfile.2 failed"
23926
23927         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23928         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23929                 error "dd with O_DIRECT large read failed"
23930         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23931                 error "compare $TMP/$tfile.3 failed"
23932 }
23933 run_test 248b "test short_io read and write for both small and large sizes"
23934
23935 test_248c() {
23936         $LCTL set_param llite.*.read_ahead_stats=c
23937         # This test compares whole file readahead to non-whole file readahead
23938         # The performance should be consistently slightly faster for whole file,
23939         # and the bug caused whole file readahead to be 80-100x slower, but to
23940         # account for possible test system lag, we require whole file to be
23941         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23942         # test
23943         local time1
23944         local time2
23945         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23946         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23947         counter=0
23948
23949         while [ $counter -lt 3 ]; do
23950                 # Increment the counter
23951                 ((counter++))
23952
23953                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23954                 rm -f $DIR/$tfile
23955                 touch $DIR/$tfile || error "(0) failed to create file"
23956                 # 64 MiB
23957                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23958                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23959                 echo "whole file readahead of 64 MiB took $time1 seconds"
23960                 $LCTL get_param llite.*.read_ahead_stats
23961
23962                 $LCTL set_param llite.*.read_ahead_stats=c
23963                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23964                 rm -f $DIR/$tfile
23965                 touch $DIR/$tfile || error "(2) failed to create file"
23966                 # 64 MiB
23967                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23968                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23969                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23970                 $LCTL get_param llite.*.read_ahead_stats
23971
23972                 # Check if time1 is not more than 1.5 times2
23973                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23974
23975                 if [[ $timecheck -eq 1 ]]; then
23976                         echo "Test passed on attempt $counter"
23977                         # Exit the loop
23978                         counter=4
23979                 else
23980                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23981                 fi
23982         done
23983         if [ $counter -eq 3 ]; then
23984                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
23985         fi
23986
23987 }
23988 run_test 248c "verify whole file read behavior"
23989
23990 test_249() { # LU-7890
23991         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23992                 skip "Need at least version 2.8.54"
23993
23994         rm -f $DIR/$tfile
23995         $LFS setstripe -c 1 $DIR/$tfile
23996         # Offset 2T == 4k * 512M
23997         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23998                 error "dd to 2T offset failed"
23999 }
24000 run_test 249 "Write above 2T file size"
24001
24002 test_250() {
24003         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
24004          && skip "no 16TB file size limit on ZFS"
24005
24006         $LFS setstripe -c 1 $DIR/$tfile
24007         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
24008         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
24009         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
24010         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
24011                 conv=notrunc,fsync && error "append succeeded"
24012         return 0
24013 }
24014 run_test 250 "Write above 16T limit"
24015
24016 test_251a() {
24017         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
24018
24019         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
24020         #Skip once - writing the first stripe will succeed
24021         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24022         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
24023                 error "short write happened"
24024
24025         $LCTL set_param fail_loc=0xa0001407 fail_val=1
24026         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
24027                 error "short read happened"
24028
24029         rm -f $DIR/$tfile
24030 }
24031 run_test 251a "Handling short read and write correctly"
24032
24033 test_251b() {
24034         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24035                 error "write $tfile failed"
24036
24037         sleep 2 && echo 12345 >> $DIR/$tfile &
24038
24039         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24040         $LCTL set_param fail_loc=0x1431 fail_val=5
24041         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24042         # 5 seconds, read 10 bytes, the short read should
24043         # report:
24044         #                start ->+ read_len -> offset_after_read read_count
24045         #     short read: 4096 ->+ 10 -> 4096 0
24046         # not:
24047         #     short read: 4096 ->+ 10 -> 4102 0
24048         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24049                         awk '/short read/ { print $7 }')
24050         (( off == 4096 )) ||
24051                 error "short read should set offset at 4096, not $off"
24052 }
24053 run_test 251b "short read restore offset correctly"
24054
24055 test_252() {
24056         remote_mds_nodsh && skip "remote MDS with nodsh"
24057         remote_ost_nodsh && skip "remote OST with nodsh"
24058         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24059                 skip_env "ldiskfs only test"
24060         fi
24061
24062         local tgt
24063         local dev
24064         local out
24065         local uuid
24066         local num
24067         local gen
24068
24069         # check lr_reader on OST0000
24070         tgt=ost1
24071         dev=$(facet_device $tgt)
24072         out=$(do_facet $tgt $LR_READER $dev)
24073         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24074         echo "$out"
24075         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24076         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24077                 error "Invalid uuid returned by $LR_READER on target $tgt"
24078         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24079
24080         # check lr_reader -c on MDT0000
24081         tgt=mds1
24082         dev=$(facet_device $tgt)
24083         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24084                 skip "$LR_READER does not support additional options"
24085         fi
24086         out=$(do_facet $tgt $LR_READER -c $dev)
24087         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24088         echo "$out"
24089         num=$(echo "$out" | grep -c "mdtlov")
24090         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24091                 error "Invalid number of mdtlov clients returned by $LR_READER"
24092         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24093
24094         # check lr_reader -cr on MDT0000
24095         out=$(do_facet $tgt $LR_READER -cr $dev)
24096         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24097         echo "$out"
24098         echo "$out" | grep -q "^reply_data:$" ||
24099                 error "$LR_READER should have returned 'reply_data' section"
24100         num=$(echo "$out" | grep -c "client_generation")
24101         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24102 }
24103 run_test 252 "check lr_reader tool"
24104
24105 test_253() {
24106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24107         remote_mds_nodsh && skip "remote MDS with nodsh"
24108         remote_mgs_nodsh && skip "remote MGS with nodsh"
24109         check_set_fallocate_or_skip
24110
24111         local ostidx=0
24112         local rc=0
24113         local ost_name=$(ostname_from_index $ostidx)
24114
24115         # on the mdt's osc
24116         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24117         do_facet $SINGLEMDS $LCTL get_param -n \
24118                 osp.$mdtosc_proc1.reserved_mb_high ||
24119                 skip  "remote MDS does not support reserved_mb_high"
24120
24121         rm -rf $DIR/$tdir
24122         wait_mds_ost_sync
24123         wait_delete_completed
24124         mkdir $DIR/$tdir
24125         stack_trap "rm -rf $DIR/$tdir"
24126
24127         pool_add $TESTNAME || error "Pool creation failed"
24128         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24129
24130         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24131                 error "Setstripe failed"
24132
24133         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24134
24135         local wms=$(ost_watermarks_get $ostidx)
24136
24137         ost_watermarks_set $ostidx 60 50
24138         stack_trap "ost_watermarks_set $ostidx $wms"
24139
24140         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24141         local size=$((free_kb * 1024))
24142
24143         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24144                 error "fallocate failed"
24145         sleep_maxage
24146
24147         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24148                         osp.$mdtosc_proc1.prealloc_status)
24149         echo "prealloc_status $oa_status"
24150
24151         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24152                 error "File creation should fail"
24153
24154         #object allocation was stopped, but we still able to append files
24155         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24156                 oflag=append || error "Append failed"
24157
24158         rm -f $DIR/$tdir/$tfile.0
24159         rm -f $DIR/$tdir/fill_ost$ostidx
24160
24161         wait_delete_completed
24162         sleep_maxage
24163
24164         for i in $(seq 10 12); do
24165                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24166                         2>/dev/null || error "File creation failed after rm"
24167         done
24168
24169         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24170                         osp.$mdtosc_proc1.prealloc_status)
24171         echo "prealloc_status $oa_status"
24172
24173         if (( oa_status != 0 )); then
24174                 error "Object allocation still disable after rm"
24175         fi
24176 }
24177 run_test 253 "Check object allocation limit"
24178
24179 test_254() {
24180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24181         remote_mds_nodsh && skip "remote MDS with nodsh"
24182
24183         local mdt=$(facet_svc $SINGLEMDS)
24184
24185         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24186                 skip "MDS does not support changelog_size"
24187
24188         local cl_user
24189
24190         changelog_register || error "changelog_register failed"
24191
24192         changelog_clear 0 || error "changelog_clear failed"
24193
24194         local size1=$(do_facet $SINGLEMDS \
24195                       $LCTL get_param -n mdd.$mdt.changelog_size)
24196         echo "Changelog size $size1"
24197
24198         rm -rf $DIR/$tdir
24199         $LFS mkdir -i 0 $DIR/$tdir
24200         # change something
24201         mkdir -p $DIR/$tdir/pics/2008/zachy
24202         touch $DIR/$tdir/pics/2008/zachy/timestamp
24203         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24204         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24205         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24206         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24207         rm $DIR/$tdir/pics/desktop.jpg
24208
24209         local size2=$(do_facet $SINGLEMDS \
24210                       $LCTL get_param -n mdd.$mdt.changelog_size)
24211         echo "Changelog size after work $size2"
24212
24213         (( $size2 > $size1 )) ||
24214                 error "new Changelog size=$size2 less than old size=$size1"
24215 }
24216 run_test 254 "Check changelog size"
24217
24218 ladvise_no_type()
24219 {
24220         local type=$1
24221         local file=$2
24222
24223         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24224                 awk -F: '{print $2}' | grep $type > /dev/null
24225         if [ $? -ne 0 ]; then
24226                 return 0
24227         fi
24228         return 1
24229 }
24230
24231 ladvise_no_ioctl()
24232 {
24233         local file=$1
24234
24235         lfs ladvise -a willread $file > /dev/null 2>&1
24236         if [ $? -eq 0 ]; then
24237                 return 1
24238         fi
24239
24240         lfs ladvise -a willread $file 2>&1 |
24241                 grep "Inappropriate ioctl for device" > /dev/null
24242         if [ $? -eq 0 ]; then
24243                 return 0
24244         fi
24245         return 1
24246 }
24247
24248 percent() {
24249         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24250 }
24251
24252 # run a random read IO workload
24253 # usage: random_read_iops <filename> <filesize> <iosize>
24254 random_read_iops() {
24255         local file=$1
24256         local fsize=$2
24257         local iosize=${3:-4096}
24258
24259         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24260                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24261 }
24262
24263 drop_file_oss_cache() {
24264         local file="$1"
24265         local nodes="$2"
24266
24267         $LFS ladvise -a dontneed $file 2>/dev/null ||
24268                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24269 }
24270
24271 ladvise_willread_performance()
24272 {
24273         local repeat=10
24274         local average_origin=0
24275         local average_cache=0
24276         local average_ladvise=0
24277
24278         for ((i = 1; i <= $repeat; i++)); do
24279                 echo "Iter $i/$repeat: reading without willread hint"
24280                 cancel_lru_locks osc
24281                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24282                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24283                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24284                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24285
24286                 cancel_lru_locks osc
24287                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24288                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24289                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24290
24291                 cancel_lru_locks osc
24292                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24293                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24294                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24295                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24296                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24297         done
24298         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24299         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24300         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24301
24302         speedup_cache=$(percent $average_cache $average_origin)
24303         speedup_ladvise=$(percent $average_ladvise $average_origin)
24304
24305         echo "Average uncached read: $average_origin"
24306         echo "Average speedup with OSS cached read:" \
24307                 "$average_cache = +$speedup_cache%"
24308         echo "Average speedup with ladvise willread:" \
24309                 "$average_ladvise = +$speedup_ladvise%"
24310
24311         local lowest_speedup=20
24312         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24313                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24314                      "got $speedup_cache%. Skipping ladvise willread check."
24315                 return 0
24316         fi
24317
24318         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24319         # it is still good to run until then to exercise 'ladvise willread'
24320         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24321                 [ "$ost1_FSTYPE" = "zfs" ] &&
24322                 echo "osd-zfs does not support dontneed or drop_caches" &&
24323                 return 0
24324
24325         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24326         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24327                 error_not_in_vm "Speedup with willread is less than " \
24328                         "$lowest_speedup%, got $speedup_ladvise%"
24329 }
24330
24331 test_255a() {
24332         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24333                 skip "lustre < 2.8.54 does not support ladvise "
24334         remote_ost_nodsh && skip "remote OST with nodsh"
24335
24336         stack_trap "rm -f $DIR/$tfile"
24337         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24338
24339         ladvise_no_type willread $DIR/$tfile &&
24340                 skip "willread ladvise is not supported"
24341
24342         ladvise_no_ioctl $DIR/$tfile &&
24343                 skip "ladvise ioctl is not supported"
24344
24345         local size_mb=100
24346         local size=$((size_mb * 1048576))
24347         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24348                 error "dd to $DIR/$tfile failed"
24349
24350         lfs ladvise -a willread $DIR/$tfile ||
24351                 error "Ladvise failed with no range argument"
24352
24353         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24354                 error "Ladvise failed with no -l or -e argument"
24355
24356         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24357                 error "Ladvise failed with only -e argument"
24358
24359         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24360                 error "Ladvise failed with only -l argument"
24361
24362         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24363                 error "End offset should not be smaller than start offset"
24364
24365         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24366                 error "End offset should not be equal to start offset"
24367
24368         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24369                 error "Ladvise failed with overflowing -s argument"
24370
24371         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24372                 error "Ladvise failed with overflowing -e argument"
24373
24374         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24375                 error "Ladvise failed with overflowing -l argument"
24376
24377         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24378                 error "Ladvise succeeded with conflicting -l and -e arguments"
24379
24380         echo "Synchronous ladvise should wait"
24381         local delay=8
24382 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24383         do_nodes $(comma_list $(osts_nodes)) \
24384                 $LCTL set_param fail_val=$delay fail_loc=0x237
24385         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24386                 $LCTL set_param fail_loc=0"
24387
24388         local start_ts=$SECONDS
24389         lfs ladvise -a willread $DIR/$tfile ||
24390                 error "Ladvise failed with no range argument"
24391         local end_ts=$SECONDS
24392         local inteval_ts=$((end_ts - start_ts))
24393
24394         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24395                 error "Synchronous advice didn't wait reply"
24396         fi
24397
24398         echo "Asynchronous ladvise shouldn't wait"
24399         local start_ts=$SECONDS
24400         lfs ladvise -a willread -b $DIR/$tfile ||
24401                 error "Ladvise failed with no range argument"
24402         local end_ts=$SECONDS
24403         local inteval_ts=$((end_ts - start_ts))
24404
24405         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24406                 error "Asynchronous advice blocked"
24407         fi
24408
24409         ladvise_willread_performance
24410 }
24411 run_test 255a "check 'lfs ladvise -a willread'"
24412
24413 facet_meminfo() {
24414         local facet=$1
24415         local info=$2
24416
24417         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24418 }
24419
24420 test_255b() {
24421         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24422                 skip "lustre < 2.8.54 does not support ladvise "
24423         remote_ost_nodsh && skip "remote OST with nodsh"
24424
24425         stack_trap "rm -f $DIR/$tfile"
24426         lfs setstripe -c 1 -i 0 $DIR/$tfile
24427
24428         ladvise_no_type dontneed $DIR/$tfile &&
24429                 skip "dontneed ladvise is not supported"
24430
24431         ladvise_no_ioctl $DIR/$tfile &&
24432                 skip "ladvise ioctl is not supported"
24433
24434         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24435                 [ "$ost1_FSTYPE" = "zfs" ] &&
24436                 skip "zfs-osd does not support 'ladvise dontneed'"
24437
24438         local size_mb=100
24439         local size=$((size_mb * 1048576))
24440         # In order to prevent disturbance of other processes, only check 3/4
24441         # of the memory usage
24442         local kibibytes=$((size_mb * 1024 * 3 / 4))
24443
24444         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24445                 error "dd to $DIR/$tfile failed"
24446
24447         #force write to complete before dropping OST cache & checking memory
24448         sync
24449
24450         local total=$(facet_meminfo ost1 MemTotal)
24451         echo "Total memory: $total KiB"
24452
24453         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24454         local before_read=$(facet_meminfo ost1 Cached)
24455         echo "Cache used before read: $before_read KiB"
24456
24457         lfs ladvise -a willread $DIR/$tfile ||
24458                 error "Ladvise willread failed"
24459         local after_read=$(facet_meminfo ost1 Cached)
24460         echo "Cache used after read: $after_read KiB"
24461
24462         lfs ladvise -a dontneed $DIR/$tfile ||
24463                 error "Ladvise dontneed again failed"
24464         local no_read=$(facet_meminfo ost1 Cached)
24465         echo "Cache used after dontneed ladvise: $no_read KiB"
24466
24467         if [ $total -lt $((before_read + kibibytes)) ]; then
24468                 echo "Memory is too small, abort checking"
24469                 return 0
24470         fi
24471
24472         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24473                 error "Ladvise willread should use more memory" \
24474                         "than $kibibytes KiB"
24475         fi
24476
24477         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24478                 error "Ladvise dontneed should release more memory" \
24479                         "than $kibibytes KiB"
24480         fi
24481 }
24482 run_test 255b "check 'lfs ladvise -a dontneed'"
24483
24484 test_255c() {
24485         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24486                 skip "lustre < 2.10.50 does not support lockahead"
24487
24488         local ost1_imp=$(get_osc_import_name client ost1)
24489         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24490                          cut -d'.' -f2)
24491         local count
24492         local new_count
24493         local difference
24494         local i
24495         local rc
24496
24497         test_mkdir -p $DIR/$tdir
24498         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24499
24500         #test 10 returns only success/failure
24501         i=10
24502         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24503         rc=$?
24504         if [ $rc -eq 255 ]; then
24505                 error "Ladvise test${i} failed, ${rc}"
24506         fi
24507
24508         #test 11 counts lock enqueue requests, all others count new locks
24509         i=11
24510         count=$(do_facet ost1 \
24511                 $LCTL get_param -n ost.OSS.ost.stats)
24512         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24513
24514         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24515         rc=$?
24516         if [ $rc -eq 255 ]; then
24517                 error "Ladvise test${i} failed, ${rc}"
24518         fi
24519
24520         new_count=$(do_facet ost1 \
24521                 $LCTL get_param -n ost.OSS.ost.stats)
24522         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24523                    awk '{ print $2 }')
24524
24525         difference="$((new_count - count))"
24526         if [ $difference -ne $rc ]; then
24527                 error "Ladvise test${i}, bad enqueue count, returned " \
24528                       "${rc}, actual ${difference}"
24529         fi
24530
24531         for i in $(seq 12 21); do
24532                 # If we do not do this, we run the risk of having too many
24533                 # locks and starting lock cancellation while we are checking
24534                 # lock counts.
24535                 cancel_lru_locks osc
24536
24537                 count=$($LCTL get_param -n \
24538                        ldlm.namespaces.$imp_name.lock_unused_count)
24539
24540                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24541                 rc=$?
24542                 if [ $rc -eq 255 ]; then
24543                         error "Ladvise test ${i} failed, ${rc}"
24544                 fi
24545
24546                 new_count=$($LCTL get_param -n \
24547                        ldlm.namespaces.$imp_name.lock_unused_count)
24548                 difference="$((new_count - count))"
24549
24550                 # Test 15 output is divided by 100 to map down to valid return
24551                 if [ $i -eq 15 ]; then
24552                         rc="$((rc * 100))"
24553                 fi
24554
24555                 if [ $difference -ne $rc ]; then
24556                         error "Ladvise test ${i}, bad lock count, returned " \
24557                               "${rc}, actual ${difference}"
24558                 fi
24559         done
24560
24561         #test 22 returns only success/failure
24562         i=22
24563         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24564         rc=$?
24565         if [ $rc -eq 255 ]; then
24566                 error "Ladvise test${i} failed, ${rc}"
24567         fi
24568 }
24569 run_test 255c "suite of ladvise lockahead tests"
24570
24571 test_256() {
24572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24573         remote_mds_nodsh && skip "remote MDS with nodsh"
24574         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24575         changelog_users $SINGLEMDS | grep "^cl" &&
24576                 skip "active changelog user"
24577
24578         local cl_user
24579         local cat_sl
24580         local mdt_dev
24581
24582         mdt_dev=$(facet_device $SINGLEMDS)
24583         echo $mdt_dev
24584
24585         changelog_register || error "changelog_register failed"
24586
24587         rm -rf $DIR/$tdir
24588         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24589
24590         changelog_clear 0 || error "changelog_clear failed"
24591
24592         # change something
24593         touch $DIR/$tdir/{1..10}
24594
24595         # stop the MDT
24596         stop $SINGLEMDS || error "Fail to stop MDT"
24597
24598         # remount the MDT
24599         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24600                 error "Fail to start MDT"
24601
24602         #after mount new plainllog is used
24603         touch $DIR/$tdir/{11..19}
24604         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24605         stack_trap "rm -f $tmpfile"
24606         cat_sl=$(do_facet $SINGLEMDS "sync; \
24607                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24608                  llog_reader $tmpfile | grep -c type=1064553b")
24609         do_facet $SINGLEMDS llog_reader $tmpfile
24610
24611         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24612
24613         changelog_clear 0 || error "changelog_clear failed"
24614
24615         cat_sl=$(do_facet $SINGLEMDS "sync; \
24616                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24617                  llog_reader $tmpfile | grep -c type=1064553b")
24618
24619         if (( cat_sl == 2 )); then
24620                 error "Empty plain llog was not deleted from changelog catalog"
24621         elif (( cat_sl != 1 )); then
24622                 error "Active plain llog shouldn't be deleted from catalog"
24623         fi
24624 }
24625 run_test 256 "Check llog delete for empty and not full state"
24626
24627 test_257() {
24628         remote_mds_nodsh && skip "remote MDS with nodsh"
24629         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24630                 skip "Need MDS version at least 2.8.55"
24631
24632         test_mkdir $DIR/$tdir
24633
24634         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24635                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24636         stat $DIR/$tdir
24637
24638 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24639         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24640         local facet=mds$((mdtidx + 1))
24641         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24642         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24643
24644         stop $facet || error "stop MDS failed"
24645         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24646                 error "start MDS fail"
24647         wait_recovery_complete $facet
24648 }
24649 run_test 257 "xattr locks are not lost"
24650
24651 # Verify we take the i_mutex when security requires it
24652 test_258a() {
24653 #define OBD_FAIL_IMUTEX_SEC 0x141c
24654         $LCTL set_param fail_loc=0x141c
24655         touch $DIR/$tfile
24656         chmod u+s $DIR/$tfile
24657         chmod a+rwx $DIR/$tfile
24658         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24659         RC=$?
24660         if [ $RC -ne 0 ]; then
24661                 error "error, failed to take i_mutex, rc=$?"
24662         fi
24663         rm -f $DIR/$tfile
24664 }
24665 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24666
24667 # Verify we do NOT take the i_mutex in the normal case
24668 test_258b() {
24669 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24670         $LCTL set_param fail_loc=0x141d
24671         touch $DIR/$tfile
24672         chmod a+rwx $DIR
24673         chmod a+rw $DIR/$tfile
24674         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24675         RC=$?
24676         if [ $RC -ne 0 ]; then
24677                 error "error, took i_mutex unnecessarily, rc=$?"
24678         fi
24679         rm -f $DIR/$tfile
24680
24681 }
24682 run_test 258b "verify i_mutex security behavior"
24683
24684 test_259() {
24685         local file=$DIR/$tfile
24686         local before
24687         local after
24688
24689         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24690
24691         stack_trap "rm -f $file" EXIT
24692
24693         wait_delete_completed
24694         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24695         echo "before: $before"
24696
24697         $LFS setstripe -i 0 -c 1 $file
24698         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24699         sync_all_data
24700         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24701         echo "after write: $after"
24702
24703 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24704         do_facet ost1 $LCTL set_param fail_loc=0x2301
24705         $TRUNCATE $file 0
24706         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24707         echo "after truncate: $after"
24708
24709         stop ost1
24710         do_facet ost1 $LCTL set_param fail_loc=0
24711         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24712         sleep 2
24713         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24714         echo "after restart: $after"
24715         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24716                 error "missing truncate?"
24717
24718         return 0
24719 }
24720 run_test 259 "crash at delayed truncate"
24721
24722 test_260() {
24723 #define OBD_FAIL_MDC_CLOSE               0x806
24724         $LCTL set_param fail_loc=0x80000806
24725         touch $DIR/$tfile
24726
24727 }
24728 run_test 260 "Check mdc_close fail"
24729
24730 ### Data-on-MDT sanity tests ###
24731 test_270a() {
24732         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24733                 skip "Need MDS version at least 2.10.55 for DoM"
24734
24735         # create DoM file
24736         local dom=$DIR/$tdir/dom_file
24737         local tmp=$DIR/$tdir/tmp_file
24738
24739         mkdir_on_mdt0 $DIR/$tdir
24740
24741         # basic checks for DoM component creation
24742         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24743                 error "Can set MDT layout to non-first entry"
24744
24745         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24746                 error "Can define multiple entries as MDT layout"
24747
24748         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24749
24750         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24751         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24752         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24753
24754         local mdtidx=$($LFS getstripe -m $dom)
24755         local mdtname=MDT$(printf %04x $mdtidx)
24756         local facet=mds$((mdtidx + 1))
24757         local space_check=1
24758
24759         # Skip free space checks with ZFS
24760         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24761
24762         # write
24763         sync
24764         local size_tmp=$((65536 * 3))
24765         local mdtfree1=$(do_facet $facet \
24766                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24767
24768         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24769         # check also direct IO along write
24770         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24771         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24772         sync
24773         cmp $tmp $dom || error "file data is different"
24774         [ $(stat -c%s $dom) == $size_tmp ] ||
24775                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24776         if [ $space_check == 1 ]; then
24777                 local mdtfree2=$(do_facet $facet \
24778                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24779
24780                 # increase in usage from by $size_tmp
24781                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24782                         error "MDT free space wrong after write: " \
24783                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24784         fi
24785
24786         # truncate
24787         local size_dom=10000
24788
24789         $TRUNCATE $dom $size_dom
24790         [ $(stat -c%s $dom) == $size_dom ] ||
24791                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24792         if [ $space_check == 1 ]; then
24793                 mdtfree1=$(do_facet $facet \
24794                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24795                 # decrease in usage from $size_tmp to new $size_dom
24796                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24797                   $(((size_tmp - size_dom) / 1024)) ] ||
24798                         error "MDT free space is wrong after truncate: " \
24799                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24800         fi
24801
24802         # append
24803         cat $tmp >> $dom
24804         sync
24805         size_dom=$((size_dom + size_tmp))
24806         [ $(stat -c%s $dom) == $size_dom ] ||
24807                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24808         if [ $space_check == 1 ]; then
24809                 mdtfree2=$(do_facet $facet \
24810                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24811                 # increase in usage by $size_tmp from previous
24812                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24813                         error "MDT free space is wrong after append: " \
24814                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24815         fi
24816
24817         # delete
24818         rm $dom
24819         if [ $space_check == 1 ]; then
24820                 mdtfree1=$(do_facet $facet \
24821                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24822                 # decrease in usage by $size_dom from previous
24823                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24824                         error "MDT free space is wrong after removal: " \
24825                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24826         fi
24827
24828         # combined striping
24829         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24830                 error "Can't create DoM + OST striping"
24831
24832         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24833         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24834         # check also direct IO along write
24835         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24836         sync
24837         cmp $tmp $dom || error "file data is different"
24838         [ $(stat -c%s $dom) == $size_tmp ] ||
24839                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24840         rm $dom $tmp
24841
24842         return 0
24843 }
24844 run_test 270a "DoM: basic functionality tests"
24845
24846 test_270b() {
24847         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24848                 skip "Need MDS version at least 2.10.55"
24849
24850         local dom=$DIR/$tdir/dom_file
24851         local max_size=1048576
24852
24853         mkdir -p $DIR/$tdir
24854         $LFS setstripe -E $max_size -L mdt $dom
24855
24856         # truncate over the limit
24857         $TRUNCATE $dom $(($max_size + 1)) &&
24858                 error "successful truncate over the maximum size"
24859         # write over the limit
24860         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24861                 error "successful write over the maximum size"
24862         # append over the limit
24863         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24864         echo "12345" >> $dom && error "successful append over the maximum size"
24865         rm $dom
24866
24867         return 0
24868 }
24869 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24870
24871 test_270c() {
24872         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24873                 skip "Need MDS version at least 2.10.55"
24874
24875         mkdir -p $DIR/$tdir
24876         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24877
24878         # check files inherit DoM EA
24879         touch $DIR/$tdir/first
24880         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24881                 error "bad pattern"
24882         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24883                 error "bad stripe count"
24884         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24885                 error "bad stripe size"
24886
24887         # check directory inherits DoM EA and uses it as default
24888         mkdir $DIR/$tdir/subdir
24889         touch $DIR/$tdir/subdir/second
24890         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24891                 error "bad pattern in sub-directory"
24892         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24893                 error "bad stripe count in sub-directory"
24894         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24895                 error "bad stripe size in sub-directory"
24896         return 0
24897 }
24898 run_test 270c "DoM: DoM EA inheritance tests"
24899
24900 test_270d() {
24901         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24902                 skip "Need MDS version at least 2.10.55"
24903
24904         mkdir -p $DIR/$tdir
24905         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24906
24907         # inherit default DoM striping
24908         mkdir $DIR/$tdir/subdir
24909         touch $DIR/$tdir/subdir/f1
24910
24911         # change default directory striping
24912         $LFS setstripe -c 1 $DIR/$tdir/subdir
24913         touch $DIR/$tdir/subdir/f2
24914         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24915                 error "wrong default striping in file 2"
24916         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24917                 error "bad pattern in file 2"
24918         return 0
24919 }
24920 run_test 270d "DoM: change striping from DoM to RAID0"
24921
24922 test_270e() {
24923         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24924                 skip "Need MDS version at least 2.10.55"
24925
24926         mkdir -p $DIR/$tdir/dom
24927         mkdir -p $DIR/$tdir/norm
24928         DOMFILES=20
24929         NORMFILES=10
24930         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24931         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24932
24933         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24934         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24935
24936         # find DoM files by layout
24937         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24938         [ $NUM -eq  $DOMFILES ] ||
24939                 error "lfs find -L: found $NUM, expected $DOMFILES"
24940         echo "Test 1: lfs find 20 DOM files by layout: OK"
24941
24942         # there should be 1 dir with default DOM striping
24943         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24944         [ $NUM -eq  1 ] ||
24945                 error "lfs find -L: found $NUM, expected 1 dir"
24946         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24947
24948         # find DoM files by stripe size
24949         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24950         [ $NUM -eq  $DOMFILES ] ||
24951                 error "lfs find -S: found $NUM, expected $DOMFILES"
24952         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24953
24954         # find files by stripe offset except DoM files
24955         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24956         [ $NUM -eq  $NORMFILES ] ||
24957                 error "lfs find -i: found $NUM, expected $NORMFILES"
24958         echo "Test 5: lfs find no DOM files by stripe index: OK"
24959         return 0
24960 }
24961 run_test 270e "DoM: lfs find with DoM files test"
24962
24963 test_270f() {
24964         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24965                 skip "Need MDS version at least 2.10.55"
24966
24967         local mdtname=${FSNAME}-MDT0000-mdtlov
24968         local dom=$DIR/$tdir/dom_file
24969         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24970                                                 lod.$mdtname.dom_stripesize)
24971         local dom_limit=131072
24972
24973         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24974         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24975                                                 lod.$mdtname.dom_stripesize)
24976         [ ${dom_limit} -eq ${dom_current} ] ||
24977                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24978
24979         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24980         $LFS setstripe -d $DIR/$tdir
24981         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24982                 error "Can't set directory default striping"
24983
24984         # exceed maximum stripe size
24985         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24986                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24987         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24988                 error "Able to create DoM component size more than LOD limit"
24989
24990         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24991         dom_current=$(do_facet mds1 $LCTL get_param -n \
24992                                                 lod.$mdtname.dom_stripesize)
24993         [ 0 -eq ${dom_current} ] ||
24994                 error "Can't set zero DoM stripe limit"
24995         rm $dom
24996
24997         # attempt to create DoM file on server with disabled DoM should
24998         # remove DoM entry from layout and be succeed
24999         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
25000                 error "Can't create DoM file (DoM is disabled)"
25001         [ $($LFS getstripe -L $dom) == "mdt" ] &&
25002                 error "File has DoM component while DoM is disabled"
25003         rm $dom
25004
25005         # attempt to create DoM file with only DoM stripe should return error
25006         $LFS setstripe -E $dom_limit -L mdt $dom &&
25007                 error "Able to create DoM-only file while DoM is disabled"
25008
25009         # too low values to be aligned with smallest stripe size 64K
25010         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
25011         dom_current=$(do_facet mds1 $LCTL get_param -n \
25012                                                 lod.$mdtname.dom_stripesize)
25013         [ 30000 -eq ${dom_current} ] &&
25014                 error "Can set too small DoM stripe limit"
25015
25016         # 64K is a minimal stripe size in Lustre, expect limit of that size
25017         [ 65536 -eq ${dom_current} ] ||
25018                 error "Limit is not set to 64K but ${dom_current}"
25019
25020         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
25021         dom_current=$(do_facet mds1 $LCTL get_param -n \
25022                                                 lod.$mdtname.dom_stripesize)
25023         echo $dom_current
25024         [ 2147483648 -eq ${dom_current} ] &&
25025                 error "Can set too large DoM stripe limit"
25026
25027         do_facet mds1 $LCTL set_param -n \
25028                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
25029         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
25030                 error "Can't create DoM component size after limit change"
25031         do_facet mds1 $LCTL set_param -n \
25032                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
25033         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25034                 error "Can't create DoM file after limit decrease"
25035         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25036                 error "Can create big DoM component after limit decrease"
25037         touch ${dom}_def ||
25038                 error "Can't create file with old default layout"
25039
25040         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25041         return 0
25042 }
25043 run_test 270f "DoM: maximum DoM stripe size checks"
25044
25045 test_270g() {
25046         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25047                 skip "Need MDS version at least 2.13.52"
25048         local dom=$DIR/$tdir/$tfile
25049
25050         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25051         local lodname=${FSNAME}-MDT0000-mdtlov
25052
25053         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25054         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25055         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25056         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25057
25058         local dom_limit=1024
25059         local dom_threshold="50%"
25060
25061         $LFS setstripe -d $DIR/$tdir
25062         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25063                 error "Can't set directory default striping"
25064
25065         do_facet mds1 $LCTL set_param -n \
25066                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25067         # set 0 threshold and create DOM file to change tunable stripesize
25068         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25069         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25070                 error "Failed to create $dom file"
25071         # now tunable dom_cur_stripesize should reach maximum
25072         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25073                                         lod.${lodname}.dom_stripesize_cur_kb)
25074         [[ $dom_current == $dom_limit ]] ||
25075                 error "Current DOM stripesize is not maximum"
25076         rm $dom
25077
25078         # set threshold for further tests
25079         do_facet mds1 $LCTL set_param -n \
25080                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25081         echo "DOM threshold is $dom_threshold free space"
25082         local dom_def
25083         local dom_set
25084         # Spoof bfree to exceed threshold
25085         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25086         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25087         for spfree in 40 20 0 15 30 55; do
25088                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25089                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25090                         error "Failed to create $dom file"
25091                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25092                                         lod.${lodname}.dom_stripesize_cur_kb)
25093                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25094                 [[ $dom_def != $dom_current ]] ||
25095                         error "Default stripe size was not changed"
25096                 if (( spfree > 0 )) ; then
25097                         dom_set=$($LFS getstripe -S $dom)
25098                         (( dom_set == dom_def * 1024 )) ||
25099                                 error "DOM component size is still old"
25100                 else
25101                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25102                                 error "DoM component is set with no free space"
25103                 fi
25104                 rm $dom
25105                 dom_current=$dom_def
25106         done
25107 }
25108 run_test 270g "DoM: default DoM stripe size depends on free space"
25109
25110 test_270h() {
25111         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25112                 skip "Need MDS version at least 2.13.53"
25113
25114         local mdtname=${FSNAME}-MDT0000-mdtlov
25115         local dom=$DIR/$tdir/$tfile
25116         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25117
25118         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25119         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25120
25121         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25122         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25123                 error "can't create OST file"
25124         # mirrored file with DOM entry in the second mirror
25125         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25126                 error "can't create mirror with DoM component"
25127
25128         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25129
25130         # DOM component in the middle and has other enries in the same mirror,
25131         # should succeed but lost DoM component
25132         $LFS setstripe --copy=${dom}_1 $dom ||
25133                 error "Can't create file from OST|DOM mirror layout"
25134         # check new file has no DoM layout after all
25135         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25136                 error "File has DoM component while DoM is disabled"
25137 }
25138 run_test 270h "DoM: DoM stripe removal when disabled on server"
25139
25140 test_270i() {
25141         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25142                 skip "Need MDS version at least 2.14.54"
25143
25144         mkdir $DIR/$tdir
25145         # DoM with plain layout
25146         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25147                 error "default plain layout with DoM must fail"
25148         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25149                 error "setstripe plain file layout with DoM must fail"
25150         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25151                 error "default DoM layout with bad striping must fail"
25152         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25153                 error "setstripe to DoM layout with bad striping must fail"
25154         return 0
25155 }
25156 run_test 270i "DoM: setting invalid DoM striping should fail"
25157
25158 test_270j() {
25159         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25160                 skip "Need MDS version at least 2.15.55.203"
25161
25162         local dom=$DIR/$tdir/$tfile
25163         local odv
25164         local ndv
25165
25166         mkdir -p $DIR/$tdir
25167
25168         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25169
25170         odv=$($LFS data_version $dom)
25171         chmod 666 $dom
25172         mv $dom ${dom}_moved
25173         link ${dom}_moved $dom
25174         setfattr -n user.attrx -v "some_attr" $dom
25175         ndv=$($LFS data_version $dom)
25176         (( $ndv == $odv )) ||
25177                 error "data version was changed by metadata operations"
25178
25179         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25180                 error "failed to write data into $dom"
25181         cancel_lru_locks mdc
25182         ndv=$($LFS data_version $dom)
25183         (( $ndv != $odv )) ||
25184                 error "data version wasn't changed on write"
25185
25186         odv=$ndv
25187         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25188         ndv=$($LFS data_version $dom)
25189         (( $ndv != $odv )) ||
25190                 error "data version wasn't changed on truncate down"
25191
25192         odv=$ndv
25193         $TRUNCATE $dom 25000
25194         ndv=$($LFS data_version $dom)
25195         (( $ndv != $odv )) ||
25196                 error "data version wasn't changed on truncate up"
25197
25198         # check also fallocate for ldiskfs
25199         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25200                 odv=$ndv
25201                 fallocate -l 1048576 $dom
25202                 ndv=$($LFS data_version $dom)
25203                 (( $ndv != $odv )) ||
25204                         error "data version wasn't changed on fallocate"
25205
25206                 odv=$ndv
25207                 fallocate -p --offset 4096 -l 4096 $dom
25208                 ndv=$($LFS data_version $dom)
25209                 (( $ndv != $odv )) ||
25210                         error "data version wasn't changed on fallocate punch"
25211         fi
25212 }
25213 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25214
25215 test_271a() {
25216         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25217                 skip "Need MDS version at least 2.10.55"
25218
25219         local dom=$DIR/$tdir/dom
25220
25221         mkdir -p $DIR/$tdir
25222
25223         $LFS setstripe -E 1024K -L mdt $dom
25224
25225         lctl set_param -n mdc.*.stats=clear
25226         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25227         cat $dom > /dev/null
25228         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25229         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25230         ls $dom
25231         rm -f $dom
25232 }
25233 run_test 271a "DoM: data is cached for read after write"
25234
25235 test_271b() {
25236         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25237                 skip "Need MDS version at least 2.10.55"
25238
25239         local dom=$DIR/$tdir/dom
25240
25241         mkdir -p $DIR/$tdir
25242
25243         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25244
25245         lctl set_param -n mdc.*.stats=clear
25246         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25247         cancel_lru_locks mdc
25248         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25249         # second stat to check size is cached on client
25250         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25251         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25252         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25253         rm -f $dom
25254 }
25255 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25256
25257 test_271ba() {
25258         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25259                 skip "Need MDS version at least 2.10.55"
25260
25261         local dom=$DIR/$tdir/dom
25262
25263         mkdir -p $DIR/$tdir
25264
25265         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25266
25267         lctl set_param -n mdc.*.stats=clear
25268         lctl set_param -n osc.*.stats=clear
25269         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25270         cancel_lru_locks mdc
25271         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25272         # second stat to check size is cached on client
25273         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25274         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25275         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25276         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25277         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25278         rm -f $dom
25279 }
25280 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25281
25282
25283 get_mdc_stats() {
25284         local mdtidx=$1
25285         local param=$2
25286         local mdt=MDT$(printf %04x $mdtidx)
25287
25288         if [ -z $param ]; then
25289                 lctl get_param -n mdc.*$mdt*.stats
25290         else
25291                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25292         fi
25293 }
25294
25295 test_271c() {
25296         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25297                 skip "Need MDS version at least 2.10.55"
25298
25299         local dom=$DIR/$tdir/dom
25300
25301         mkdir -p $DIR/$tdir
25302
25303         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25304
25305         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25306         local facet=mds$((mdtidx + 1))
25307
25308         cancel_lru_locks mdc
25309         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25310         createmany -o $dom 1000
25311         lctl set_param -n mdc.*.stats=clear
25312         smalliomany -w $dom 1000 200
25313         get_mdc_stats $mdtidx
25314         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25315         # Each file has 1 open, 1 IO enqueues, total 2000
25316         # but now we have also +1 getxattr for security.capability, total 3000
25317         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25318         unlinkmany $dom 1000
25319
25320         cancel_lru_locks mdc
25321         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25322         createmany -o $dom 1000
25323         lctl set_param -n mdc.*.stats=clear
25324         smalliomany -w $dom 1000 200
25325         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25326         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25327         # for OPEN and IO lock.
25328         [ $((enq - enq_2)) -ge 1000 ] ||
25329                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25330         unlinkmany $dom 1000
25331         return 0
25332 }
25333 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25334
25335 cleanup_271def_tests() {
25336         trap 0
25337         rm -f $1
25338 }
25339
25340 test_271d() {
25341         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25342                 skip "Need MDS version at least 2.10.57"
25343
25344         local dom=$DIR/$tdir/dom
25345         local tmp=$TMP/$tfile
25346         trap "cleanup_271def_tests $tmp" EXIT
25347
25348         mkdir -p $DIR/$tdir
25349
25350         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25351
25352         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25353
25354         cancel_lru_locks mdc
25355         dd if=/dev/urandom of=$tmp bs=1000 count=1
25356         dd if=$tmp of=$dom bs=1000 count=1
25357         cancel_lru_locks mdc
25358
25359         cat /etc/hosts >> $tmp
25360         lctl set_param -n mdc.*.stats=clear
25361
25362         # append data to the same file it should update local page
25363         echo "Append to the same page"
25364         cat /etc/hosts >> $dom
25365         local num=$(get_mdc_stats $mdtidx ost_read)
25366         local ra=$(get_mdc_stats $mdtidx req_active)
25367         local rw=$(get_mdc_stats $mdtidx req_waittime)
25368
25369         [ -z $num ] || error "$num READ RPC occured"
25370         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25371         echo "... DONE"
25372
25373         # compare content
25374         cmp $tmp $dom || error "file miscompare"
25375
25376         cancel_lru_locks mdc
25377         lctl set_param -n mdc.*.stats=clear
25378
25379         echo "Open and read file"
25380         cat $dom > /dev/null
25381         local num=$(get_mdc_stats $mdtidx ost_read)
25382         local ra=$(get_mdc_stats $mdtidx req_active)
25383         local rw=$(get_mdc_stats $mdtidx req_waittime)
25384
25385         [ -z $num ] || error "$num READ RPC occured"
25386         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25387         echo "... DONE"
25388
25389         # compare content
25390         cmp $tmp $dom || error "file miscompare"
25391
25392         return 0
25393 }
25394 run_test 271d "DoM: read on open (1K file in reply buffer)"
25395
25396 test_271f() {
25397         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25398                 skip "Need MDS version at least 2.10.57"
25399
25400         local dom=$DIR/$tdir/dom
25401         local tmp=$TMP/$tfile
25402         trap "cleanup_271def_tests $tmp" EXIT
25403
25404         mkdir -p $DIR/$tdir
25405
25406         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25407
25408         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25409
25410         cancel_lru_locks mdc
25411         dd if=/dev/urandom of=$tmp bs=265000 count=1
25412         dd if=$tmp of=$dom bs=265000 count=1
25413         cancel_lru_locks mdc
25414         cat /etc/hosts >> $tmp
25415         lctl set_param -n mdc.*.stats=clear
25416
25417         echo "Append to the same page"
25418         cat /etc/hosts >> $dom
25419         local num=$(get_mdc_stats $mdtidx ost_read)
25420         local ra=$(get_mdc_stats $mdtidx req_active)
25421         local rw=$(get_mdc_stats $mdtidx req_waittime)
25422
25423         [ -z $num ] || error "$num READ RPC occured"
25424         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25425         echo "... DONE"
25426
25427         # compare content
25428         cmp $tmp $dom || error "file miscompare"
25429
25430         cancel_lru_locks mdc
25431         lctl set_param -n mdc.*.stats=clear
25432
25433         echo "Open and read file"
25434         cat $dom > /dev/null
25435         local num=$(get_mdc_stats $mdtidx ost_read)
25436         local ra=$(get_mdc_stats $mdtidx req_active)
25437         local rw=$(get_mdc_stats $mdtidx req_waittime)
25438
25439         [ -z $num ] && num=0
25440         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25441         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25442         echo "... DONE"
25443
25444         # compare content
25445         cmp $tmp $dom || error "file miscompare"
25446
25447         return 0
25448 }
25449 run_test 271f "DoM: read on open (200K file and read tail)"
25450
25451 test_271g() {
25452         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25453                 skip "Skipping due to old client or server version"
25454
25455         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25456         # to get layout
25457         $CHECKSTAT -t file $DIR1/$tfile
25458
25459         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25460         MULTIOP_PID=$!
25461         sleep 1
25462         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25463         $LCTL set_param fail_loc=0x80000314
25464         rm $DIR1/$tfile || error "Unlink fails"
25465         RC=$?
25466         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25467         [ $RC -eq 0 ] || error "Failed write to stale object"
25468 }
25469 run_test 271g "Discard DoM data vs client flush race"
25470
25471 test_272a() {
25472         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25473                 skip "Need MDS version at least 2.11.50"
25474
25475         local dom=$DIR/$tdir/dom
25476         mkdir -p $DIR/$tdir
25477
25478         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25479         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25480                 error "failed to write data into $dom"
25481         local old_md5=$(md5sum $dom)
25482
25483         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25484                 error "failed to migrate to the same DoM component"
25485
25486         local new_md5=$(md5sum $dom)
25487
25488         [ "$old_md5" == "$new_md5" ] ||
25489                 error "md5sum differ: $old_md5, $new_md5"
25490
25491         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25492                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25493 }
25494 run_test 272a "DoM migration: new layout with the same DOM component"
25495
25496 test_272b() {
25497         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25498                 skip "Need MDS version at least 2.11.50"
25499
25500         local dom=$DIR/$tdir/dom
25501         mkdir -p $DIR/$tdir
25502         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25503         stack_trap "rm -rf $DIR/$tdir"
25504
25505         local mdtidx=$($LFS getstripe -m $dom)
25506         local mdtname=MDT$(printf %04x $mdtidx)
25507         local facet=mds$((mdtidx + 1))
25508
25509         local mdtfree1=$(do_facet $facet \
25510                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25511         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25512                 error "failed to write data into $dom"
25513         local old_md5=$(md5sum $dom)
25514         cancel_lru_locks mdc
25515         local mdtfree1=$(do_facet $facet \
25516                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25517
25518         $LFS migrate -c2 $dom ||
25519                 error "failed to migrate to the new composite layout"
25520         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25521                 error "MDT stripe was not removed"
25522         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25523                 error "$dir1 shouldn't have DATAVER EA"
25524
25525         cancel_lru_locks mdc
25526         local new_md5=$(md5sum $dom)
25527         [ "$old_md5" == "$new_md5" ] ||
25528                 error "$old_md5 != $new_md5"
25529
25530         # Skip free space checks with ZFS
25531         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25532                 local mdtfree2=$(do_facet $facet \
25533                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25534                 [ $mdtfree2 -gt $mdtfree1 ] ||
25535                         error "MDT space is not freed after migration"
25536         fi
25537         return 0
25538 }
25539 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25540
25541 test_272c() {
25542         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25543                 skip "Need MDS version at least 2.11.50"
25544
25545         local dom=$DIR/$tdir/$tfile
25546         mkdir -p $DIR/$tdir
25547         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25548         stack_trap "rm -rf $DIR/$tdir"
25549
25550         local mdtidx=$($LFS getstripe -m $dom)
25551         local mdtname=MDT$(printf %04x $mdtidx)
25552         local facet=mds$((mdtidx + 1))
25553
25554         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25555                 error "failed to write data into $dom"
25556         local old_md5=$(md5sum $dom)
25557         cancel_lru_locks mdc
25558         local mdtfree1=$(do_facet $facet \
25559                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25560
25561         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25562                 error "failed to migrate to the new composite layout"
25563         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25564                 error "MDT stripe was not removed"
25565
25566         cancel_lru_locks mdc
25567         local new_md5=$(md5sum $dom)
25568         [ "$old_md5" == "$new_md5" ] ||
25569                 error "$old_md5 != $new_md5"
25570
25571         # Skip free space checks with ZFS
25572         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25573                 local mdtfree2=$(do_facet $facet \
25574                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25575                 [ $mdtfree2 -gt $mdtfree1 ] ||
25576                         error "MDS space is not freed after migration"
25577         fi
25578         return 0
25579 }
25580 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25581
25582 test_272d() {
25583         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25584                 skip "Need MDS version at least 2.12.55"
25585
25586         local dom=$DIR/$tdir/$tfile
25587         mkdir -p $DIR/$tdir
25588         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25589
25590         local mdtidx=$($LFS getstripe -m $dom)
25591         local mdtname=MDT$(printf %04x $mdtidx)
25592         local facet=mds$((mdtidx + 1))
25593
25594         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25595                 error "failed to write data into $dom"
25596         local old_md5=$(md5sum $dom)
25597         cancel_lru_locks mdc
25598         local mdtfree1=$(do_facet $facet \
25599                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25600
25601         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25602                 error "failed mirroring to the new composite layout"
25603         $LFS mirror resync $dom ||
25604                 error "failed mirror resync"
25605         $LFS mirror split --mirror-id 1 -d $dom ||
25606                 error "failed mirror split"
25607
25608         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25609                 error "MDT stripe was not removed"
25610
25611         cancel_lru_locks mdc
25612         local new_md5=$(md5sum $dom)
25613         [ "$old_md5" == "$new_md5" ] ||
25614                 error "$old_md5 != $new_md5"
25615
25616         # Skip free space checks with ZFS
25617         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25618                 local mdtfree2=$(do_facet $facet \
25619                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25620                 [ $mdtfree2 -gt $mdtfree1 ] ||
25621                         error "MDS space is not freed after DOM mirror deletion"
25622         fi
25623         return 0
25624 }
25625 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25626
25627 test_272e() {
25628         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25629                 skip "Need MDS version at least 2.12.55"
25630
25631         local dom=$DIR/$tdir/$tfile
25632         mkdir -p $DIR/$tdir
25633         $LFS setstripe -c 2 $dom
25634
25635         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25636                 error "failed to write data into $dom"
25637         local old_md5=$(md5sum $dom)
25638         cancel_lru_locks
25639
25640         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25641                 error "failed mirroring to the DOM layout"
25642         $LFS mirror resync $dom ||
25643                 error "failed mirror resync"
25644         $LFS mirror split --mirror-id 1 -d $dom ||
25645                 error "failed mirror split"
25646
25647         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25648                 error "MDT stripe wasn't set"
25649
25650         cancel_lru_locks
25651         local new_md5=$(md5sum $dom)
25652         [ "$old_md5" == "$new_md5" ] ||
25653                 error "$old_md5 != $new_md5"
25654
25655         return 0
25656 }
25657 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25658
25659 test_272f() {
25660         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25661                 skip "Need MDS version at least 2.12.55"
25662
25663         local dom=$DIR/$tdir/$tfile
25664         mkdir -p $DIR/$tdir
25665         $LFS setstripe -c 2 $dom
25666
25667         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25668                 error "failed to write data into $dom"
25669         local old_md5=$(md5sum $dom)
25670         cancel_lru_locks
25671
25672         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25673                 error "failed migrating to the DOM file"
25674
25675         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25676                 error "MDT stripe wasn't set"
25677
25678         cancel_lru_locks
25679         local new_md5=$(md5sum $dom)
25680         [ "$old_md5" != "$new_md5" ] &&
25681                 error "$old_md5 != $new_md5"
25682
25683         return 0
25684 }
25685 run_test 272f "DoM migration: OST-striped file to DOM file"
25686
25687 test_273a() {
25688         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25689                 skip "Need MDS version at least 2.11.50"
25690
25691         # Layout swap cannot be done if either file has DOM component,
25692         # this will never be supported, migration should be used instead
25693
25694         local dom=$DIR/$tdir/$tfile
25695         mkdir -p $DIR/$tdir
25696
25697         $LFS setstripe -c2 ${dom}_plain
25698         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25699         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25700                 error "can swap layout with DoM component"
25701         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25702                 error "can swap layout with DoM component"
25703
25704         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25705         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25706                 error "can swap layout with DoM component"
25707         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25708                 error "can swap layout with DoM component"
25709         return 0
25710 }
25711 run_test 273a "DoM: layout swapping should fail with DOM"
25712
25713 test_273b() {
25714         mkdir -p $DIR/$tdir
25715         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25716
25717 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25718         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25719
25720         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25721 }
25722 run_test 273b "DoM: race writeback and object destroy"
25723
25724 test_273c() {
25725         mkdir -p $DIR/$tdir
25726         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25727
25728         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25729         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25730
25731         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25732 }
25733 run_test 273c "race writeback and object destroy"
25734
25735 test_275() {
25736         remote_ost_nodsh && skip "remote OST with nodsh"
25737         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25738                 skip "Need OST version >= 2.10.57"
25739
25740         local file=$DIR/$tfile
25741         local oss
25742
25743         oss=$(comma_list $(osts_nodes))
25744
25745         dd if=/dev/urandom of=$file bs=1M count=2 ||
25746                 error "failed to create a file"
25747         stack_trap "rm -f $file"
25748         cancel_lru_locks osc
25749
25750         #lock 1
25751         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25752                 error "failed to read a file"
25753
25754 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25755         $LCTL set_param fail_loc=0x8000031f
25756
25757         cancel_lru_locks osc &
25758         sleep 1
25759
25760 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25761         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25762         #IO takes another lock, but matches the PENDING one
25763         #and places it to the IO RPC
25764         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25765                 error "failed to read a file with PENDING lock"
25766 }
25767 run_test 275 "Read on a canceled duplicate lock"
25768
25769 test_276() {
25770         remote_ost_nodsh && skip "remote OST with nodsh"
25771         local pid
25772
25773         do_facet ost1 "(while true; do \
25774                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25775                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25776         pid=$!
25777
25778         for LOOP in $(seq 20); do
25779                 stop ost1
25780                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25781         done
25782         kill -9 $pid
25783         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25784                 rm $TMP/sanity_276_pid"
25785 }
25786 run_test 276 "Race between mount and obd_statfs"
25787
25788 test_277() {
25789         $LCTL set_param ldlm.namespaces.*.lru_size=0
25790         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25791         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25792                           awk '/^used_mb/ { print $2 }')
25793         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25794         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25795                 oflag=direct conv=notrunc
25796         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25797                     awk '/^used_mb/ { print $2 }')
25798         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25799 }
25800 run_test 277 "Direct IO shall drop page cache"
25801
25802 test_278() {
25803         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25804         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25805         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25806                 skip "needs the same host for mdt1 mdt2" && return
25807
25808         local pid1
25809         local pid2
25810
25811 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25812         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25813         stop mds2 &
25814         pid2=$!
25815
25816         stop mds1
25817
25818         echo "Starting MDTs"
25819         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25820         wait $pid2
25821 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25822 #will return NULL
25823         do_facet mds2 $LCTL set_param fail_loc=0
25824
25825         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25826         wait_recovery_complete mds2
25827 }
25828 run_test 278 "Race starting MDS between MDTs stop/start"
25829
25830 test_280() {
25831         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25832                 skip "Need MGS version at least 2.13.52"
25833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25834         combined_mgs_mds || skip "needs combined MGS/MDT"
25835
25836         umount_client $MOUNT
25837 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25838         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25839
25840         mount_client $MOUNT &
25841         sleep 1
25842         stop mgs || error "stop mgs failed"
25843         #for a race mgs would crash
25844         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25845         # make sure we unmount client before remounting
25846         wait
25847         umount_client $MOUNT
25848         mount_client $MOUNT || error "mount client failed"
25849 }
25850 run_test 280 "Race between MGS umount and client llog processing"
25851
25852 cleanup_test_300() {
25853         trap 0
25854         umask $SAVE_UMASK
25855 }
25856
25857 test_striped_dir() {
25858         local mdt_index=$1
25859         local stripe_count=$2
25860         local overstriping=$3
25861         local stripe_index
25862         local getstripe_count
25863
25864         mkdir -p $DIR/$tdir
25865
25866         SAVE_UMASK=$(umask)
25867         trap cleanup_test_300 RETURN EXIT
25868
25869         if [ -z $overstriping ]; then
25870                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25871                                         -o 755 $DIR/$tdir/striped_dir ||
25872                         error "set striped dir error"
25873         else
25874                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25875                                         -o 755 $DIR/$tdir/striped_dir ||
25876                         error "set striped dir error"
25877         fi
25878
25879         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25880         [ "$mode" = "755" ] || error "expect 755 got $mode"
25881
25882         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25883                 error "getdirstripe failed"
25884         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25885         if [ "$getstripe_count" != "$stripe_count" ]; then
25886                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25887         fi
25888         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25889         if [ "$getstripe_count" != "$stripe_count" ]; then
25890                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25891         fi
25892
25893         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25894         if [ "$stripe_index" != "$mdt_index" ]; then
25895                 error "stripe_index is $stripe_index, expect $mdt_index"
25896         fi
25897
25898         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25899                 error "nlink error after create striped dir"
25900
25901         mkdir $DIR/$tdir/striped_dir/a
25902         mkdir $DIR/$tdir/striped_dir/b
25903
25904         stat $DIR/$tdir/striped_dir/a ||
25905                 error "create dir under striped dir failed"
25906         stat $DIR/$tdir/striped_dir/b ||
25907                 error "create dir under striped dir failed"
25908
25909         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25910                 error "nlink error after mkdir"
25911
25912         rmdir $DIR/$tdir/striped_dir/a
25913         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25914                 error "nlink error after rmdir"
25915
25916         rmdir $DIR/$tdir/striped_dir/b
25917         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25918                 error "nlink error after rmdir"
25919
25920         chattr +i $DIR/$tdir/striped_dir
25921         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25922                 error "immutable flags not working under striped dir!"
25923         chattr -i $DIR/$tdir/striped_dir
25924
25925         rmdir $DIR/$tdir/striped_dir ||
25926                 error "rmdir striped dir error"
25927
25928         cleanup_test_300
25929
25930         true
25931 }
25932
25933 test_300a() {
25934         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25935                 skip "skipped for lustre < 2.7.0"
25936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25937         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25938
25939         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25940         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25941 }
25942 run_test 300a "basic striped dir sanity test"
25943
25944 test_300b() {
25945         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25946                 skip "skipped for lustre < 2.7.0"
25947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25948         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25949
25950         local i
25951         local mtime1
25952         local mtime2
25953         local mtime3
25954
25955         test_mkdir $DIR/$tdir || error "mkdir fail"
25956         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25957                 error "set striped dir error"
25958         for i in {0..9}; do
25959                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25960                 sleep 1
25961                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25962                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25963                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25964                 sleep 1
25965                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25966                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25967                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25968         done
25969         true
25970 }
25971 run_test 300b "check ctime/mtime for striped dir"
25972
25973 test_300c() {
25974         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25975                 skip "skipped for lustre < 2.7.0"
25976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25978
25979         local file_count
25980
25981         mkdir_on_mdt0 $DIR/$tdir
25982         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25983                 error "set striped dir error"
25984
25985         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25986                 error "chown striped dir failed"
25987
25988         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25989                 error "create 5k files failed"
25990
25991         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25992
25993         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25994
25995         rm -rf $DIR/$tdir
25996 }
25997 run_test 300c "chown && check ls under striped directory"
25998
25999 test_300d() {
26000         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
26001                 skip "skipped for lustre < 2.7.0"
26002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26004
26005         local stripe_count
26006         local file
26007
26008         mkdir -p $DIR/$tdir
26009         $LFS setstripe -c 2 $DIR/$tdir
26010
26011         #local striped directory
26012         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26013                 error "set striped dir error"
26014         #look at the directories for debug purposes
26015         ls -l $DIR/$tdir
26016         $LFS getdirstripe $DIR/$tdir
26017         ls -l $DIR/$tdir/striped_dir
26018         $LFS getdirstripe $DIR/$tdir/striped_dir
26019         createmany -o $DIR/$tdir/striped_dir/f 10 ||
26020                 error "create 10 files failed"
26021
26022         #remote striped directory
26023         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
26024                 error "set striped dir error"
26025         #look at the directories for debug purposes
26026         ls -l $DIR/$tdir
26027         $LFS getdirstripe $DIR/$tdir
26028         ls -l $DIR/$tdir/remote_striped_dir
26029         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
26030         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
26031                 error "create 10 files failed"
26032
26033         for file in $(find $DIR/$tdir); do
26034                 stripe_count=$($LFS getstripe -c $file)
26035                 [ $stripe_count -eq 2 ] ||
26036                         error "wrong stripe $stripe_count for $file"
26037         done
26038
26039         rm -rf $DIR/$tdir
26040 }
26041 run_test 300d "check default stripe under striped directory"
26042
26043 test_300e() {
26044         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26045                 skip "Need MDS version at least 2.7.55"
26046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26048
26049         local stripe_count
26050         local file
26051
26052         mkdir -p $DIR/$tdir
26053
26054         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26055                 error "set striped dir error"
26056
26057         touch $DIR/$tdir/striped_dir/a
26058         touch $DIR/$tdir/striped_dir/b
26059         touch $DIR/$tdir/striped_dir/c
26060
26061         mkdir $DIR/$tdir/striped_dir/dir_a
26062         mkdir $DIR/$tdir/striped_dir/dir_b
26063         mkdir $DIR/$tdir/striped_dir/dir_c
26064
26065         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26066                 error "set striped adir under striped dir error"
26067
26068         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26069                 error "set striped bdir under striped dir error"
26070
26071         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26072                 error "set striped cdir under striped dir error"
26073
26074         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26075                 error "rename dir under striped dir fails"
26076
26077         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26078                 error "rename dir under different stripes fails"
26079
26080         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26081                 error "rename file under striped dir should succeed"
26082
26083         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26084                 error "rename dir under striped dir should succeed"
26085
26086         rm -rf $DIR/$tdir
26087 }
26088 run_test 300e "check rename under striped directory"
26089
26090 test_300f() {
26091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26093         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26094                 skip "Need MDS version at least 2.7.55"
26095
26096         local stripe_count
26097         local file
26098
26099         rm -rf $DIR/$tdir
26100         mkdir -p $DIR/$tdir
26101
26102         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26103                 error "set striped dir error"
26104
26105         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26106                 error "set striped dir error"
26107
26108         touch $DIR/$tdir/striped_dir/a
26109         mkdir $DIR/$tdir/striped_dir/dir_a
26110         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26111                 error "create striped dir under striped dir fails"
26112
26113         touch $DIR/$tdir/striped_dir1/b
26114         mkdir $DIR/$tdir/striped_dir1/dir_b
26115         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26116                 error "create striped dir under striped dir fails"
26117
26118         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26119                 error "rename dir under different striped dir should fail"
26120
26121         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26122                 error "rename striped dir under diff striped dir should fail"
26123
26124         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26125                 error "rename file under diff striped dirs fails"
26126
26127         rm -rf $DIR/$tdir
26128 }
26129 run_test 300f "check rename cross striped directory"
26130
26131 test_300_check_default_striped_dir()
26132 {
26133         local dirname=$1
26134         local default_count=$2
26135         local default_index=$3
26136         local stripe_count
26137         local stripe_index
26138         local dir_stripe_index
26139         local dir
26140
26141         echo "checking $dirname $default_count $default_index"
26142         $LFS setdirstripe -D -c $default_count -i $default_index \
26143                                 -H all_char $DIR/$tdir/$dirname ||
26144                 error "set default stripe on striped dir error"
26145         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26146         [ $stripe_count -eq $default_count ] ||
26147                 error "expect $default_count get $stripe_count for $dirname"
26148
26149         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26150         [ $stripe_index -eq $default_index ] ||
26151                 error "expect $default_index get $stripe_index for $dirname"
26152
26153         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26154                                                 error "create dirs failed"
26155
26156         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26157         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26158         for dir in $(find $DIR/$tdir/$dirname/*); do
26159                 stripe_count=$($LFS getdirstripe -c $dir)
26160                 (( $stripe_count == $default_count )) ||
26161                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26162                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26163                 error "stripe count $default_count != $stripe_count for $dir"
26164
26165                 stripe_index=$($LFS getdirstripe -i $dir)
26166                 [ $default_index -eq -1 ] ||
26167                         [ $stripe_index -eq $default_index ] ||
26168                         error "$stripe_index != $default_index for $dir"
26169
26170                 #check default stripe
26171                 stripe_count=$($LFS getdirstripe -D -c $dir)
26172                 [ $stripe_count -eq $default_count ] ||
26173                 error "default count $default_count != $stripe_count for $dir"
26174
26175                 stripe_index=$($LFS getdirstripe -D -i $dir)
26176                 [ $stripe_index -eq $default_index ] ||
26177                 error "default index $default_index != $stripe_index for $dir"
26178         done
26179         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26180 }
26181
26182 test_300g() {
26183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26184         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26185                 skip "Need MDS version at least 2.7.55"
26186
26187         local dir
26188         local stripe_count
26189         local stripe_index
26190
26191         mkdir_on_mdt0 $DIR/$tdir
26192         mkdir $DIR/$tdir/normal_dir
26193
26194         #Checking when client cache stripe index
26195         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26196         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26197                 error "create striped_dir failed"
26198
26199         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26200                 error "create dir0 fails"
26201         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26202         [ $stripe_index -eq 0 ] ||
26203                 error "dir0 expect index 0 got $stripe_index"
26204
26205         mkdir $DIR/$tdir/striped_dir/dir1 ||
26206                 error "create dir1 fails"
26207         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26208         [ $stripe_index -eq 1 ] ||
26209                 error "dir1 expect index 1 got $stripe_index"
26210
26211         #check default stripe count/stripe index
26212         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26213         test_300_check_default_striped_dir normal_dir 1 0
26214         test_300_check_default_striped_dir normal_dir -1 1
26215         test_300_check_default_striped_dir normal_dir 2 -1
26216
26217         #delete default stripe information
26218         echo "delete default stripeEA"
26219         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26220                 error "set default stripe on striped dir error"
26221
26222         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26223         for dir in $(find $DIR/$tdir/normal_dir/*); do
26224                 stripe_count=$($LFS getdirstripe -c $dir)
26225                 [ $stripe_count -eq 0 ] ||
26226                         error "expect 1 get $stripe_count for $dir"
26227         done
26228 }
26229 run_test 300g "check default striped directory for normal directory"
26230
26231 test_300h() {
26232         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26233         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26234                 skip "Need MDS version at least 2.7.55"
26235
26236         local dir
26237         local stripe_count
26238
26239         mkdir $DIR/$tdir
26240         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26241                 error "set striped dir error"
26242
26243         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26244         test_300_check_default_striped_dir striped_dir 1 0
26245         test_300_check_default_striped_dir striped_dir -1 1
26246         test_300_check_default_striped_dir striped_dir 2 -1
26247
26248         #delete default stripe information
26249         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26250                 error "set default stripe on striped dir error"
26251
26252         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26253         for dir in $(find $DIR/$tdir/striped_dir/*); do
26254                 stripe_count=$($LFS getdirstripe -c $dir)
26255                 [ $stripe_count -eq 0 ] ||
26256                         error "expect 1 get $stripe_count for $dir"
26257         done
26258 }
26259 run_test 300h "check default striped directory for striped directory"
26260
26261 test_300i() {
26262         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26263         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26264         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26265                 skip "Need MDS version at least 2.7.55"
26266
26267         local stripe_count
26268         local file
26269
26270         mkdir $DIR/$tdir
26271
26272         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26273                 error "set striped dir error"
26274
26275         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26276                 error "create files under striped dir failed"
26277
26278         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26279                 error "set striped hashdir error"
26280
26281         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26282                 error "create dir0 under hash dir failed"
26283         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26284                 error "create dir1 under hash dir failed"
26285         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26286                 error "create dir2 under hash dir failed"
26287
26288         # unfortunately, we need to umount to clear dir layout cache for now
26289         # once we fully implement dir layout, we can drop this
26290         umount_client $MOUNT || error "umount failed"
26291         mount_client $MOUNT || error "mount failed"
26292
26293         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26294         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26295         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26296
26297         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26298                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26299                         error "create crush2 dir $tdir/hashdir/d3 failed"
26300                 $LFS find -H crush2 $DIR/$tdir/hashdir
26301                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26302                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26303
26304                 # mkdir with an invalid hash type (hash=fail_val) from client
26305                 # should be replaced on MDS with a valid (default) hash type
26306                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26307                 $LCTL set_param fail_loc=0x1901 fail_val=99
26308                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26309
26310                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26311                 local expect=$(do_facet mds1 \
26312                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26313                 [[ $hash == $expect ]] ||
26314                         error "d99 hash '$hash' != expected hash '$expect'"
26315         fi
26316
26317         #set the stripe to be unknown hash type on read
26318         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26319         $LCTL set_param fail_loc=0x1901 fail_val=99
26320         for ((i = 0; i < 10; i++)); do
26321                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26322                         error "stat f-$i failed"
26323                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26324         done
26325
26326         touch $DIR/$tdir/striped_dir/f0 &&
26327                 error "create under striped dir with unknown hash should fail"
26328
26329         $LCTL set_param fail_loc=0
26330
26331         umount_client $MOUNT || error "umount failed"
26332         mount_client $MOUNT || error "mount failed"
26333
26334         return 0
26335 }
26336 run_test 300i "client handle unknown hash type striped directory"
26337
26338 test_300j() {
26339         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26341         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26342                 skip "Need MDS version at least 2.7.55"
26343
26344         local stripe_count
26345         local file
26346
26347         mkdir $DIR/$tdir
26348
26349         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26350         $LCTL set_param fail_loc=0x1702
26351         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26352                 error "set striped dir error"
26353
26354         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26355                 error "create files under striped dir failed"
26356
26357         $LCTL set_param fail_loc=0
26358
26359         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26360
26361         return 0
26362 }
26363 run_test 300j "test large update record"
26364
26365 test_300k() {
26366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26367         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26368         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26369                 skip "Need MDS version at least 2.7.55"
26370
26371         # this test needs a huge transaction
26372         local kb
26373         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26374              osd*.$FSNAME-MDT0000.kbytestotal")
26375         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26376
26377         local stripe_count
26378         local file
26379
26380         mkdir $DIR/$tdir
26381
26382         #define OBD_FAIL_LARGE_STRIPE   0x1703
26383         $LCTL set_param fail_loc=0x1703
26384         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26385                 error "set striped dir error"
26386         $LCTL set_param fail_loc=0
26387
26388         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26389                 error "getstripeddir fails"
26390         rm -rf $DIR/$tdir/striped_dir ||
26391                 error "unlink striped dir fails"
26392
26393         return 0
26394 }
26395 run_test 300k "test large striped directory"
26396
26397 test_300l() {
26398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26400         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26401                 skip "Need MDS version at least 2.7.55"
26402
26403         local stripe_index
26404
26405         test_mkdir -p $DIR/$tdir/striped_dir
26406         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26407                         error "chown $RUNAS_ID failed"
26408         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26409                 error "set default striped dir failed"
26410
26411         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26412         $LCTL set_param fail_loc=0x80000158
26413         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26414
26415         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26416         [ $stripe_index -eq 1 ] ||
26417                 error "expect 1 get $stripe_index for $dir"
26418 }
26419 run_test 300l "non-root user to create dir under striped dir with stale layout"
26420
26421 test_300m() {
26422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26423         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26424         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26425                 skip "Need MDS version at least 2.7.55"
26426
26427         mkdir -p $DIR/$tdir/striped_dir
26428         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26429                 error "set default stripes dir error"
26430
26431         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26432
26433         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26434         [ $stripe_count -eq 0 ] ||
26435                         error "expect 0 get $stripe_count for a"
26436
26437         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26438                 error "set default stripes dir error"
26439
26440         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26441
26442         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26443         [ $stripe_count -eq 0 ] ||
26444                         error "expect 0 get $stripe_count for b"
26445
26446         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26447                 error "set default stripes dir error"
26448
26449         mkdir $DIR/$tdir/striped_dir/c &&
26450                 error "default stripe_index is invalid, mkdir c should fails"
26451
26452         rm -rf $DIR/$tdir || error "rmdir fails"
26453 }
26454 run_test 300m "setstriped directory on single MDT FS"
26455
26456 cleanup_300n() {
26457         local list=$(comma_list $(mdts_nodes))
26458
26459         trap 0
26460         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26461 }
26462
26463 test_300n() {
26464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26466         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26467                 skip "Need MDS version at least 2.7.55"
26468         remote_mds_nodsh && skip "remote MDS with nodsh"
26469
26470         local stripe_index
26471         local list=$(comma_list $(mdts_nodes))
26472
26473         trap cleanup_300n RETURN EXIT
26474         mkdir -p $DIR/$tdir
26475         chmod 777 $DIR/$tdir
26476         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26477                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26478                 error "create striped dir succeeds with gid=0"
26479
26480         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26481         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26482                 error "create striped dir fails with gid=-1"
26483
26484         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26485         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26486                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26487                 error "set default striped dir succeeds with gid=0"
26488
26489
26490         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26491         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26492                 error "set default striped dir fails with gid=-1"
26493
26494
26495         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26496         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26497                                         error "create test_dir fails"
26498         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26499                                         error "create test_dir1 fails"
26500         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26501                                         error "create test_dir2 fails"
26502         cleanup_300n
26503 }
26504 run_test 300n "non-root user to create dir under striped dir with default EA"
26505
26506 test_300o() {
26507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26508         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26509         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26510                 skip "Need MDS version at least 2.7.55"
26511
26512         local numfree1
26513         local numfree2
26514
26515         mkdir -p $DIR/$tdir
26516
26517         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26518         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26519         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26520                 skip "not enough free inodes $numfree1 $numfree2"
26521         fi
26522
26523         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26524         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26525         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26526                 skip "not enough free space $numfree1 $numfree2"
26527         fi
26528
26529         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26530                 error "setdirstripe fails"
26531
26532         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26533                 error "create dirs fails"
26534
26535         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26536         ls $DIR/$tdir/striped_dir > /dev/null ||
26537                 error "ls striped dir fails"
26538         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26539                 error "unlink big striped dir fails"
26540 }
26541 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26542
26543 test_300p() {
26544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26545         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26546         remote_mds_nodsh && skip "remote MDS with nodsh"
26547
26548         mkdir_on_mdt0 $DIR/$tdir
26549
26550         #define OBD_FAIL_OUT_ENOSPC     0x1704
26551         do_facet mds2 lctl set_param fail_loc=0x80001704
26552         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26553                  && error "create striped directory should fail"
26554
26555         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26556
26557         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26558         true
26559 }
26560 run_test 300p "create striped directory without space"
26561
26562 test_300q() {
26563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26565
26566         local fd=$(free_fd)
26567         local cmd="exec $fd<$tdir"
26568         cd $DIR
26569         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26570         eval $cmd
26571         cmd="exec $fd<&-"
26572         trap "eval $cmd" EXIT
26573         cd $tdir || error "cd $tdir fails"
26574         rmdir  ../$tdir || error "rmdir $tdir fails"
26575         mkdir local_dir && error "create dir succeeds"
26576         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26577         eval $cmd
26578         return 0
26579 }
26580 run_test 300q "create remote directory under orphan directory"
26581
26582 test_300r() {
26583         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26584                 skip "Need MDS version at least 2.7.55" && return
26585         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26586
26587         mkdir $DIR/$tdir
26588
26589         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26590                 error "set striped dir error"
26591
26592         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26593                 error "getstripeddir fails"
26594
26595         local stripe_count
26596         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26597                       awk '/lmv_stripe_count:/ { print $2 }')
26598
26599         [ $MDSCOUNT -ne $stripe_count ] &&
26600                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26601
26602         rm -rf $DIR/$tdir/striped_dir ||
26603                 error "unlink striped dir fails"
26604 }
26605 run_test 300r "test -1 striped directory"
26606
26607 test_300s_helper() {
26608         local count=$1
26609
26610         local stripe_dir=$DIR/$tdir/striped_dir.$count
26611
26612         $LFS mkdir -c $count $stripe_dir ||
26613                 error "lfs mkdir -c error"
26614
26615         $LFS getdirstripe $stripe_dir ||
26616                 error "lfs getdirstripe fails"
26617
26618         local stripe_count
26619         stripe_count=$($LFS getdirstripe $stripe_dir |
26620                       awk '/lmv_stripe_count:/ { print $2 }')
26621
26622         [ $count -ne $stripe_count ] &&
26623                 error_noexit "bad stripe count $stripe_count expected $count"
26624
26625         local dupe_stripes
26626         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26627                 awk '/0x/ {count[$1] += 1}; END {
26628                         for (idx in count) {
26629                                 if (count[idx]>1) {
26630                                         print "index " idx " count " count[idx]
26631                                 }
26632                         }
26633                 }')
26634
26635         if [[ -n "$dupe_stripes" ]] ; then
26636                 lfs getdirstripe $stripe_dir
26637                 error_noexit "Dupe MDT above: $dupe_stripes "
26638         fi
26639
26640         rm -rf $stripe_dir ||
26641                 error_noexit "unlink $stripe_dir fails"
26642 }
26643
26644 test_300s() {
26645         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26646                 skip "Need MDS version at least 2.7.55" && return
26647         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26648
26649         mkdir $DIR/$tdir
26650         for count in $(seq 2 $MDSCOUNT); do
26651                 test_300s_helper $count
26652         done
26653 }
26654 run_test 300s "test lfs mkdir -c without -i"
26655
26656 test_300t() {
26657         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26658                 skip "need MDS 2.14.55 or later"
26659         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26660
26661         local testdir="$DIR/$tdir/striped_dir"
26662         local dir1=$testdir/dir1
26663         local dir2=$testdir/dir2
26664
26665         mkdir -p $testdir
26666
26667         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26668                 error "failed to set default stripe count for $testdir"
26669
26670         mkdir $dir1
26671         local stripe_count=$($LFS getdirstripe -c $dir1)
26672
26673         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26674
26675         local max_count=$((MDSCOUNT - 1))
26676         local mdts=$(comma_list $(mdts_nodes))
26677
26678         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26679         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26680
26681         mkdir $dir2
26682         stripe_count=$($LFS getdirstripe -c $dir2)
26683
26684         (( $stripe_count == $max_count )) || error "wrong stripe count"
26685 }
26686 run_test 300t "test max_mdt_stripecount"
26687
26688 MDT_OVSTRP_VER="2.15.60"
26689 # 300u family tests MDT overstriping
26690 test_300ua() {
26691         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26692
26693         local setcount=$((MDSCOUNT * 2))
26694
26695         local expected_count
26696
26697         mkdir $DIR/$tdir
26698         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26699                 error "(0) failed basic overstriped dir creation test"
26700         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26701
26702         # This does a basic interop test - if the MDS does not support mdt
26703         # overstriping, we should get stripes == number of MDTs
26704         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26705                 expected_count=$MDSCOUNT
26706         else
26707                 expected_count=$setcount
26708         fi
26709         (( getstripe_count == expected_count )) ||
26710                 error "(1) incorrect stripe count for simple overstriped dir"
26711
26712         rm -rf $DIR/$tdir/${tdir}.0 ||
26713                 error "(2) unable to rm overstriped dir"
26714
26715         # Tests after this require overstriping support
26716         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26717                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26718
26719         test_striped_dir 0 $setcount true ||
26720                 error "(3)failed on overstriped dir"
26721         test_striped_dir 1 $setcount true ||
26722                 error "(4)failed on overstriped dir"
26723
26724         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26725
26726         test_striped_dir 0 $setcount true ||
26727                 error "(5)failed on overstriped dir"
26728 }
26729 run_test 300ua "basic overstriped dir sanity test"
26730
26731 test_300ub() {
26732         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26733                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26734         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26735
26736         mkdir $DIR/$tdir
26737
26738         echo "Testing invalid stripe count, failure expected"
26739         local setcount=$((MDSCOUNT * 2))
26740
26741         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26742         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26743
26744         (( getstripe_count <= MDSCOUNT )) ||
26745                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26746
26747         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26748         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26749         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26750
26751         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26752
26753         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26754         (( getstripe_count == maxcount )) ||
26755                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26756
26757         # Test specific striping with -i
26758         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26759
26760         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26761         (( getstripe_count == 4 )) ||
26762                 error "(2)stripe_count is $getstripe_count, expect 4"
26763
26764         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26765                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26766
26767         [[ -n "$nonzeroindices" ]] ||
26768                 error "(3) stripes indices not all 0: $nonzeroindices"
26769
26770         # Test specific striping with too many stripes on one MDT
26771         echo "Testing invalid striping, failure expected"
26772         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26773         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26774         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26775                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26776         echo "stripes on MDT0: $getstripe_count"
26777         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26778                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26779
26780         setcount=$((MDSCOUNT * 2))
26781         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26782                 error "(5) can't setdirstripe with manually set hash function"
26783
26784         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26785         (( getstripe_count == setcount )) ||
26786                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26787
26788         setcount=$((MDSCOUNT * 2))
26789         mkdir $DIR/${tdir}.5
26790         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26791                 error "(7) can't setdirstripe with manually set hash function"
26792         mkdir $DIR/${tdir}.5/${tdir}.6
26793
26794         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26795         (( getstripe_count == setcount )) ||
26796                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26797 }
26798 run_test 300ub "test MDT overstriping interface & limits"
26799
26800 test_300uc() {
26801         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26802                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26803         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26804
26805         mkdir $DIR/$tdir
26806
26807         local setcount=$((MDSCOUNT * 2))
26808
26809         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26810
26811         mkdir $DIR/$tdir/${tdir}.1
26812
26813         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26814
26815         (( getstripe_count == setcount )) ||
26816                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26817
26818         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26819
26820         local getstripe_count=$($LFS getdirstripe -c \
26821                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26822
26823         (( getstripe_count == setcount )) ||
26824                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26825 }
26826 run_test 300uc "test MDT overstriping as default & inheritance"
26827
26828 test_300ud() {
26829         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26830                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26831         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26832
26833         local mdts=$(comma_list $(mdts_nodes))
26834         local timeout=100
26835
26836         local restripe_status
26837         local delta
26838         local i
26839
26840         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26841
26842         # in case "crush" hash type is not set
26843         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26844
26845         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26846                            mdt.*MDT0000.enable_dir_restripe)
26847         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26848         stack_trap "do_nodes $mdts $LCTL set_param \
26849                     mdt.*.enable_dir_restripe=$restripe_status"
26850
26851         mkdir $DIR/$tdir
26852         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26853                 error "create files under remote dir failed $i"
26854         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26855                 error "create dirs under remote dir failed $i"
26856
26857         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26858
26859         (( setcount < 13 )) || setcount=12
26860         for i in $(seq 2 $setcount); do
26861                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26862                 $LFS setdirstripe -C $i $DIR/$tdir ||
26863                         error "split -C $i $tdir failed"
26864                 wait_update $HOSTNAME \
26865                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26866                         error "dir split not finished"
26867                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26868                         awk '/migrate/ {sum += $2} END { print sum }')
26869                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26870                 # delta is around total_files/stripe_count, deviation 3%
26871                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26872                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26873         done
26874 }
26875 run_test 300ud "dir split"
26876
26877 test_300ue() {
26878         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26879                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26880         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26881
26882         local mdts=$(comma_list $(mdts_nodes))
26883         local timeout=100
26884
26885         local restripe_status
26886         local delta
26887         local c
26888
26889         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26890
26891         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26892
26893         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26894                            mdt.*MDT0000.enable_dir_restripe)
26895         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26896         stack_trap "do_nodes $mdts $LCTL set_param \
26897                     mdt.*.enable_dir_restripe=$restripe_status"
26898
26899         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26900
26901         (( setcount < 13 )) || setcount=12
26902         test_mkdir -C $setcount -H crush $DIR/$tdir
26903         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26904                 error "create files under remote dir failed"
26905         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26906                 error "create dirs under remote dir failed"
26907
26908         for c in $(seq $((setcount - 1)) -1 1); do
26909                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26910                 $LFS setdirstripe -C $c $DIR/$tdir ||
26911                         error "split -C $c $tdir failed"
26912                 wait_update $HOSTNAME \
26913                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26914                         error "dir merge not finished"
26915                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26916                         awk '/migrate/ {sum += $2} END { print sum }')
26917                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26918                 # delta is around total_files/stripe_count, deviation 3%
26919                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26920                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26921         done
26922 }
26923 run_test 300ue "dir merge"
26924
26925 test_300uf() {
26926         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26927                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26928         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26929
26930         # maximum amount of local locks:
26931         # parent striped dir - 2 locks
26932         # new stripe in parent to migrate to - 1 lock
26933         # source and target - 2 locks
26934         # Total 5 locks for regular file
26935         #
26936         # NB: Overstriping should add several extra local locks
26937         # FIXME: Remove this once understood
26938         #lctl set_param *debug=-1 debug_mb=10000
26939         lctl clear
26940         lctl mark "touch/create"
26941         mkdir -p $DIR/$tdir
26942         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26943         local setcount=$((MDSCOUNT * 5))
26944
26945         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26946         touch $DIR/$tdir/dir1/eee
26947
26948         lctl mark "hardlinks"
26949         # create 4 hardlink for 4 more locks
26950         # Total: 9 locks > RS_MAX_LOCKS (8)
26951         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26952         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26953         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26954         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26955         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26956         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26957         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26958         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26959
26960         lctl mark "cancel lru"
26961         cancel_lru_locks mdc
26962
26963         lctl mark "migrate"
26964         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26965                 error "migrate dir fails"
26966
26967         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26968 }
26969 run_test 300uf "migrate with too many local locks"
26970
26971 test_300ug() {
26972         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26973                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26974         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26975
26976         mkdir -p $DIR/$tdir
26977         local migrate_dir=$DIR/$tdir/migrate_dir
26978         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26979         local setcount2=$((setcount - 2))
26980
26981         $LFS setdirstripe -c 2 $migrate_dir ||
26982                 error "(0) failed to create striped directory"
26983
26984         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26985                 error "(1)failed to migrate to overstriped directory"
26986         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26987
26988         (( getstripe_count == setcount )) ||
26989                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26990         touch $DIR/$tdir/migrate_dir/$tfile ||
26991                 error "(3)failed to create file in overstriped directory"
26992         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26993                 error "(4)failed to migrate overstriped directory"
26994         # Check stripe count after migration
26995         $LFS getdirstripe $migrate_dir
26996         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26997         (( getstripe_count == setcount2 )) ||
26998                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26999
27000         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
27001 }
27002 run_test 300ug "migrate overstriped dirs"
27003
27004 prepare_remote_file() {
27005         mkdir $DIR/$tdir/src_dir ||
27006                 error "create remote source failed"
27007
27008         cp /etc/hosts $DIR/$tdir/src_dir/a ||
27009                  error "cp to remote source failed"
27010         touch $DIR/$tdir/src_dir/a
27011
27012         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
27013                 error "create remote target dir failed"
27014
27015         touch $DIR/$tdir/tgt_dir/b
27016
27017         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
27018                 error "rename dir cross MDT failed!"
27019
27020         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
27021                 error "src_child still exists after rename"
27022
27023         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
27024                 error "missing file(a) after rename"
27025
27026         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
27027                 error "diff after rename"
27028 }
27029
27030 test_310a() {
27031         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27033
27034         local remote_file=$DIR/$tdir/tgt_dir/b
27035
27036         mkdir -p $DIR/$tdir
27037
27038         prepare_remote_file || error "prepare remote file failed"
27039
27040         #open-unlink file
27041         $OPENUNLINK $remote_file $remote_file ||
27042                 error "openunlink $remote_file failed"
27043         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27044 }
27045 run_test 310a "open unlink remote file"
27046
27047 test_310b() {
27048         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27050
27051         local remote_file=$DIR/$tdir/tgt_dir/b
27052
27053         mkdir -p $DIR/$tdir
27054
27055         prepare_remote_file || error "prepare remote file failed"
27056
27057         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27058         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27059         $CHECKSTAT -t file $remote_file || error "check file failed"
27060 }
27061 run_test 310b "unlink remote file with multiple links while open"
27062
27063 test_310c() {
27064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27065         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27066
27067         local remote_file=$DIR/$tdir/tgt_dir/b
27068
27069         mkdir -p $DIR/$tdir
27070
27071         prepare_remote_file || error "prepare remote file failed"
27072
27073         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27074         multiop_bg_pause $remote_file O_uc ||
27075                         error "mulitop failed for remote file"
27076         MULTIPID=$!
27077         $MULTIOP $DIR/$tfile Ouc
27078         kill -USR1 $MULTIPID
27079         wait $MULTIPID
27080 }
27081 run_test 310c "open-unlink remote file with multiple links"
27082
27083 #LU-4825
27084 test_311() {
27085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27086         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27087         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27088                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27089         remote_mds_nodsh && skip "remote MDS with nodsh"
27090
27091         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27092         local mdts=$(comma_list $(mdts_nodes))
27093
27094         mkdir -p $DIR/$tdir
27095         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27096         createmany -o $DIR/$tdir/$tfile. 1000
27097
27098         # statfs data is not real time, let's just calculate it
27099         old_iused=$((old_iused + 1000))
27100
27101         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27102                         osp.*OST0000*MDT0000.create_count")
27103         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27104                                 osp.*OST0000*MDT0000.max_create_count")
27105         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27106
27107         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27108         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27109         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27110
27111         unlinkmany $DIR/$tdir/$tfile. 1000
27112
27113         do_nodes $mdts "$LCTL set_param -n \
27114                         osp.*OST0000*.max_create_count=$max_count"
27115         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27116                 do_nodes $mdts "$LCTL set_param -n \
27117                                 osp.*OST0000*.create_count=$count"
27118         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27119                         grep "=0" && error "create_count is zero"
27120
27121         local new_iused
27122         for i in $(seq 120); do
27123                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27124                 # system may be too busy to destroy all objs in time, use
27125                 # a somewhat small value to not fail autotest
27126                 [ $((old_iused - new_iused)) -gt 400 ] && break
27127                 sleep 1
27128         done
27129
27130         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27131         [ $((old_iused - new_iused)) -gt 400 ] ||
27132                 error "objs not destroyed after unlink"
27133 }
27134 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27135
27136 zfs_get_objid()
27137 {
27138         local ost=$1
27139         local tf=$2
27140         local fid=($($LFS getstripe $tf | grep 0x))
27141         local seq=${fid[3]#0x}
27142         local objid=${fid[1]}
27143
27144         local vdevdir=$(dirname $(facet_vdevice $ost))
27145         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27146         local zfs_zapid=$(do_facet $ost $cmd |
27147                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27148                           awk '/Object/{getline; print $1}')
27149         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27150                           awk "/$objid = /"'{printf $3}')
27151
27152         echo $zfs_objid
27153 }
27154
27155 zfs_object_blksz() {
27156         local ost=$1
27157         local objid=$2
27158
27159         local vdevdir=$(dirname $(facet_vdevice $ost))
27160         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27161         local blksz=$(do_facet $ost $cmd $objid |
27162                       awk '/dblk/{getline; printf $4}')
27163
27164         case "${blksz: -1}" in
27165                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27166                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27167                 *) ;;
27168         esac
27169
27170         echo $blksz
27171 }
27172
27173 test_312() { # LU-4856
27174         remote_ost_nodsh && skip "remote OST with nodsh"
27175         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27176
27177         local max_blksz=$(do_facet ost1 \
27178                           $ZFS get -p recordsize $(facet_device ost1) |
27179                           awk '!/VALUE/{print $3}')
27180         local tf=$DIR/$tfile
27181
27182         $LFS setstripe -c1 $tf
27183         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27184
27185         # Get ZFS object id
27186         local zfs_objid=$(zfs_get_objid $facet $tf)
27187         # block size change by sequential overwrite
27188         local bs
27189
27190         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27191                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27192
27193                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27194                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27195         done
27196         rm -f $tf
27197
27198         $LFS setstripe -c1 $tf
27199         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27200
27201         # block size change by sequential append write
27202         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27203         zfs_objid=$(zfs_get_objid $facet $tf)
27204         local count
27205
27206         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27207                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27208                         oflag=sync conv=notrunc
27209
27210                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27211                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27212                         error "blksz error, actual $blksz, " \
27213                                 "expected: 2 * $count * $PAGE_SIZE"
27214         done
27215         rm -f $tf
27216
27217         # random write
27218         $LFS setstripe -c1 $tf
27219         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27220         zfs_objid=$(zfs_get_objid $facet $tf)
27221
27222         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27223         blksz=$(zfs_object_blksz $facet $zfs_objid)
27224         (( blksz == PAGE_SIZE )) ||
27225                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27226
27227         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27228         blksz=$(zfs_object_blksz $facet $zfs_objid)
27229         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27230
27231         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27232         blksz=$(zfs_object_blksz $facet $zfs_objid)
27233         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27234 }
27235 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27236
27237 test_313() {
27238         remote_ost_nodsh && skip "remote OST with nodsh"
27239
27240         local file=$DIR/$tfile
27241
27242         rm -f $file
27243         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27244
27245         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27246         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27247         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27248                 error "write should failed"
27249         do_facet ost1 "$LCTL set_param fail_loc=0"
27250         rm -f $file
27251 }
27252 run_test 313 "io should fail after last_rcvd update fail"
27253
27254 test_314() {
27255         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27256
27257         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27258         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27259         rm -f $DIR/$tfile
27260         wait_delete_completed
27261         do_facet ost1 "$LCTL set_param fail_loc=0"
27262 }
27263 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27264
27265 test_315() { # LU-618
27266         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27267
27268         local file=$DIR/$tfile
27269         rm -f $file
27270
27271         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27272                 error "multiop file write failed"
27273         $MULTIOP $file oO_RDONLY:r4063232_c &
27274         PID=$!
27275
27276         sleep 2
27277
27278         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27279         kill -USR1 $PID
27280
27281         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27282         rm -f $file
27283 }
27284 run_test 315 "read should be accounted"
27285
27286 test_316() {
27287         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27288         large_xattr_enabled || skip "ea_inode feature disabled"
27289
27290         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27291         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27292         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27293         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27294
27295         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27296 }
27297 run_test 316 "lfs migrate of file with large_xattr enabled"
27298
27299 test_317() {
27300         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27301                 skip "Need MDS version at least 2.11.53"
27302         if [ "$ost1_FSTYPE" == "zfs" ]; then
27303                 skip "LU-10370: no implementation for ZFS"
27304         fi
27305
27306         local trunc_sz
27307         local grant_blk_size
27308
27309         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27310                         awk '/grant_block_size:/ { print $2; exit; }')
27311         #
27312         # Create File of size 5M. Truncate it to below size's and verify
27313         # blocks count.
27314         #
27315         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27316                 error "Create file $DIR/$tfile failed"
27317         stack_trap "rm -f $DIR/$tfile" EXIT
27318
27319         for trunc_sz in 2097152 4097 4000 509 0; do
27320                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27321                         error "truncate $tfile to $trunc_sz failed"
27322                 local sz=$(stat --format=%s $DIR/$tfile)
27323                 local blk=$(stat --format=%b $DIR/$tfile)
27324                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27325                                      grant_blk_size) * 8))
27326
27327                 if [[ $blk -ne $trunc_blk ]]; then
27328                         $(which stat) $DIR/$tfile
27329                         error "Expected Block $trunc_blk got $blk for $tfile"
27330                 fi
27331
27332                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27333                         error "Expected Size $trunc_sz got $sz for $tfile"
27334         done
27335
27336         #
27337         # sparse file test
27338         # Create file with a hole and write actual 65536 bytes which aligned
27339         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27340         #
27341         local bs=65536
27342         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27343                 error "Create file : $DIR/$tfile"
27344
27345         #
27346         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27347         # blocks. The block count must drop to 8.
27348         #
27349         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27350                 ((bs - grant_blk_size) + 1)))
27351         $TRUNCATE $DIR/$tfile $trunc_sz ||
27352                 error "truncate $tfile to $trunc_sz failed"
27353
27354         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27355         sz=$(stat --format=%s $DIR/$tfile)
27356         blk=$(stat --format=%b $DIR/$tfile)
27357
27358         if [[ $blk -ne $trunc_bsz ]]; then
27359                 $(which stat) $DIR/$tfile
27360                 error "Expected Block $trunc_bsz got $blk for $tfile"
27361         fi
27362
27363         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27364                 error "Expected Size $trunc_sz got $sz for $tfile"
27365 }
27366 run_test 317 "Verify blocks get correctly update after truncate"
27367
27368 test_318() {
27369         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27370         local old_max_active=$($LCTL get_param -n \
27371                             ${llite_name}.max_read_ahead_async_active \
27372                             2>/dev/null)
27373
27374         $LCTL set_param llite.*.max_read_ahead_async_active=256
27375         local max_active=$($LCTL get_param -n \
27376                            ${llite_name}.max_read_ahead_async_active \
27377                            2>/dev/null)
27378         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27379
27380         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27381                 error "set max_read_ahead_async_active should succeed"
27382
27383         $LCTL set_param llite.*.max_read_ahead_async_active=512
27384         max_active=$($LCTL get_param -n \
27385                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27386         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27387
27388         # restore @max_active
27389         [ $old_max_active -ne 0 ] && $LCTL set_param \
27390                 llite.*.max_read_ahead_async_active=$old_max_active
27391
27392         local old_threshold=$($LCTL get_param -n \
27393                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27394         local max_per_file_mb=$($LCTL get_param -n \
27395                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27396
27397         local invalid=$(($max_per_file_mb + 1))
27398         $LCTL set_param \
27399                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27400                         && error "set $invalid should fail"
27401
27402         local valid=$(($invalid - 1))
27403         $LCTL set_param \
27404                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27405                         error "set $valid should succeed"
27406         local threshold=$($LCTL get_param -n \
27407                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27408         [ $threshold -eq $valid ] || error \
27409                 "expect threshold $valid got $threshold"
27410         $LCTL set_param \
27411                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27412 }
27413 run_test 318 "Verify async readahead tunables"
27414
27415 test_319() {
27416         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27417
27418         local before=$(date +%s)
27419         local evict
27420         local mdir=$DIR/$tdir
27421         local file=$mdir/xxx
27422
27423         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27424         touch $file
27425
27426 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27427         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27428         $LFS migrate -m1 $mdir &
27429
27430         sleep 1
27431         dd if=$file of=/dev/null
27432         wait
27433         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27434           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27435
27436         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27437 }
27438 run_test 319 "lost lease lock on migrate error"
27439
27440 test_350() {
27441         local mdts=$(comma_list $(mdts_nodes))
27442
27443         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27444         stack_trap "rm -r $DIR/$tdir"
27445
27446         #force 1/100 of replies to take "NID mismatch" codepath
27447         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27448         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27449
27450         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27451         stack_trap "killall -9 ls || killall -9 ls"
27452
27453         cp -a /etc $DIR/$tdir || error "cp failed"
27454 }
27455 run_test 350 "force NID mismatch path to be exercised"
27456
27457 test_360() {
27458         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27459                 skip "Need OST version at least 2.15.58.96"
27460         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27461
27462         check_set_fallocate_or_skip
27463         local param="osd-ldiskfs.delayed_unlink_mb"
27464         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27465
27466         do_facet ost1 "$LCTL set_param $param=1MiB"
27467         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27468
27469         mkdir $DIR/$tdir/
27470         do_facet ost1 $LCTL set_param debug=+inode
27471         do_facet ost1 $LCTL clear
27472         local files=100
27473
27474         for ((i = 0; i < $files; i++)); do
27475                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27476                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27477         done
27478         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27479
27480         for ((i = 0; i < $files; i++)); do
27481                 unlink $DIR/$tdir/$tfile.$i ||
27482                         error "unlink $DIR/$tdir/$tfile.$i failed"
27483         done
27484
27485         local count=0
27486         local loop
27487
27488         for (( loop = 0; loop < 30 && count < min; loop++)); do
27489                 sleep 1
27490                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27491                 echo "Count[$loop]: $count"
27492         done
27493         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27494 }
27495 run_test 360 "ldiskfs unlink in a separate thread"
27496
27497 test_398a() { # LU-4198
27498         local ost1_imp=$(get_osc_import_name client ost1)
27499         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27500                          cut -d'.' -f2)
27501
27502         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27503         stack_trap "rm -f $DIR/$tfile"
27504         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27505
27506         # request a new lock on client
27507         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27508
27509         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27510         local lock_count=$($LCTL get_param -n \
27511                            ldlm.namespaces.$imp_name.lru_size)
27512         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27513
27514         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27515
27516         # no lock cached, should use lockless DIO and not enqueue new lock
27517         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27518         lock_count=$($LCTL get_param -n \
27519                      ldlm.namespaces.$imp_name.lru_size)
27520         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27521
27522         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27523
27524         # no lock cached, should use locked DIO append
27525         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27526                 conv=notrunc || error "DIO append failed"
27527         lock_count=$($LCTL get_param -n \
27528                      ldlm.namespaces.$imp_name.lru_size)
27529         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27530 }
27531 run_test 398a "direct IO should cancel lock otherwise lockless"
27532
27533 test_398b() { # LU-4198
27534         local before=$(date +%s)
27535         local njobs=4
27536         local size=48
27537
27538         which fio || skip_env "no fio installed"
27539         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27540         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27541
27542         # Single page, multiple pages, stripe size, 4*stripe size
27543         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27544                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27545                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27546                         --numjobs=$njobs --fallocate=none \
27547                         --iodepth=16 --allow_file_create=0 \
27548                         --size=$((size/njobs))M \
27549                         --filename=$DIR/$tfile &
27550                 bg_pid=$!
27551
27552                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27553                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27554                         --numjobs=$njobs --fallocate=none \
27555                         --iodepth=16 --allow_file_create=0 \
27556                         --size=$((size/njobs))M \
27557                         --filename=$DIR/$tfile || true
27558                 wait $bg_pid
27559         done
27560
27561         evict=$(do_facet client $LCTL get_param \
27562                 osc.$FSNAME-OST*-osc-*/state |
27563             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27564
27565         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27566                 (do_facet client $LCTL get_param \
27567                         osc.$FSNAME-OST*-osc-*/state;
27568                     error "eviction happened: $evict before:$before")
27569
27570         rm -f $DIR/$tfile
27571 }
27572 run_test 398b "DIO and buffer IO race"
27573
27574 test_398c() { # LU-4198
27575         local ost1_imp=$(get_osc_import_name client ost1)
27576         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27577                          cut -d'.' -f2)
27578
27579         which fio || skip_env "no fio installed"
27580
27581         saved_debug=$($LCTL get_param -n debug)
27582         $LCTL set_param debug=0
27583
27584         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27585         ((size /= 1024)) # by megabytes
27586         ((size /= 2)) # write half of the OST at most
27587         [ $size -gt 40 ] && size=40 #reduce test time anyway
27588
27589         $LFS setstripe -c 1 $DIR/$tfile
27590
27591         # it seems like ldiskfs reserves more space than necessary if the
27592         # writing blocks are not mapped, so it extends the file firstly
27593         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27594         cancel_lru_locks osc
27595
27596         # clear and verify rpc_stats later
27597         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27598
27599         local njobs=4
27600         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27601         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27602                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27603                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27604                 --filename=$DIR/$tfile
27605         [ $? -eq 0 ] || error "fio write error"
27606
27607         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27608                 error "Locks were requested while doing AIO"
27609
27610         # get the percentage of 1-page I/O
27611         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27612                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27613                 awk '{print $7}')
27614         (( $pct <= 50 )) || {
27615                 $LCTL get_param osc.${imp_name}.rpc_stats
27616                 error "$pct% of I/O are 1-page"
27617         }
27618
27619         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27620         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27621                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27622                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27623                 --filename=$DIR/$tfile
27624         [ $? -eq 0 ] || error "fio mixed read write error"
27625
27626         echo "AIO with large block size ${size}M"
27627         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27628                 --numjobs=1 --fallocate=none --ioengine=libaio \
27629                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27630                 --filename=$DIR/$tfile
27631         [ $? -eq 0 ] || error "fio large block size failed"
27632
27633         rm -f $DIR/$tfile
27634         $LCTL set_param debug="$saved_debug"
27635 }
27636 run_test 398c "run fio to test AIO"
27637
27638 test_398d() { #  LU-13846
27639         which aiocp || skip_env "no aiocp installed"
27640         local aio_file=$DIR/$tfile.aio
27641
27642         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27643
27644         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27645         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27646         stack_trap "rm -f $DIR/$tfile $aio_file"
27647
27648         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27649
27650         # test memory unaligned aio
27651         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27652                 error "unaligned aio failed"
27653         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27654
27655         rm -f $DIR/$tfile $aio_file
27656 }
27657 run_test 398d "run aiocp to verify block size > stripe size"
27658
27659 test_398e() {
27660         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27661         touch $DIR/$tfile.new
27662         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27663 }
27664 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27665
27666 test_398f() { #  LU-14687
27667         which aiocp || skip_env "no aiocp installed"
27668         local aio_file=$DIR/$tfile.aio
27669
27670         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27671
27672         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27673         stack_trap "rm -f $DIR/$tfile $aio_file"
27674
27675         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27676         $LCTL set_param fail_loc=0x1418
27677         # make sure we don't crash and fail properly
27678         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27679                 error "aio with page allocation failure succeeded"
27680         $LCTL set_param fail_loc=0
27681         diff $DIR/$tfile $aio_file
27682         [[ $? != 0 ]] || error "no diff after failed aiocp"
27683 }
27684 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27685
27686 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27687 # stripe and i/o size must be > stripe size
27688 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27689 # single RPC in flight.  This test shows async DIO submission is working by
27690 # showing multiple RPCs in flight.
27691 test_398g() { #  LU-13798
27692         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27693
27694         # We need to do some i/o first to acquire enough grant to put our RPCs
27695         # in flight; otherwise a new connection may not have enough grant
27696         # available
27697         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27698                 error "parallel dio failed"
27699         stack_trap "rm -f $DIR/$tfile"
27700
27701         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27702         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27703         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27704         stack_trap "$LCTL set_param -n $pages_per_rpc"
27705
27706         # Recreate file so it's empty
27707         rm -f $DIR/$tfile
27708         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27709         #Pause rpc completion to guarantee we see multiple rpcs in flight
27710         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27711         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27712         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27713
27714         # Clear rpc stats
27715         $LCTL set_param osc.*.rpc_stats=c
27716
27717         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27718                 error "parallel dio failed"
27719         stack_trap "rm -f $DIR/$tfile"
27720
27721         $LCTL get_param osc.*-OST0000-*.rpc_stats
27722         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27723                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27724                 grep "8:" | awk '{print $8}')
27725         # We look at the "8 rpcs in flight" field, and verify A) it is present
27726         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27727         # as expected for an 8M DIO to a file with 1M stripes.
27728         # NB: There is occasionally a mystery extra write RPC to a different
27729         # file.  I can't identify why that's happening, so we set up a margin
27730         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27731         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27732
27733         # Verify turning off parallel dio works as expected
27734         # Clear rpc stats
27735         $LCTL set_param osc.*.rpc_stats=c
27736         $LCTL set_param llite.*.parallel_dio=0
27737         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27738
27739         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27740                 error "dio with parallel dio disabled failed"
27741
27742         # Ideally, we would see only one RPC in flight here, but there is an
27743         # unavoidable race between i/o completion and RPC in flight counting,
27744         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27745         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27746         # So instead we just verify it's always < 8.
27747         $LCTL get_param osc.*-OST0000-*.rpc_stats
27748         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27749                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27750                 grep '^$' -B1 | grep . | awk '{print $1}')
27751         [ $ret != "8:" ] ||
27752                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27753 }
27754 run_test 398g "verify parallel dio async RPC submission"
27755
27756 test_398h() { #  LU-13798
27757         local dio_file=$DIR/$tfile.dio
27758
27759         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27760
27761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27762         stack_trap "rm -f $DIR/$tfile $dio_file"
27763
27764         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27765                 error "parallel dio failed"
27766         diff $DIR/$tfile $dio_file
27767         [[ $? == 0 ]] || error "file diff after aiocp"
27768 }
27769 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27770
27771 test_398i() { #  LU-13798
27772         local dio_file=$DIR/$tfile.dio
27773
27774         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27775
27776         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27777         stack_trap "rm -f $DIR/$tfile $dio_file"
27778
27779         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27780         $LCTL set_param fail_loc=0x1418
27781         # make sure we don't crash and fail properly
27782         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27783                 error "parallel dio page allocation failure succeeded"
27784         diff $DIR/$tfile $dio_file
27785         [[ $? != 0 ]] || error "no diff after failed aiocp"
27786 }
27787 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27788
27789 test_398j() { #  LU-13798
27790         # Stripe size > RPC size but less than i/o size tests split across
27791         # stripes and RPCs for individual i/o op
27792         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27793
27794         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27795         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27796         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27797         stack_trap "$LCTL set_param -n $pages_per_rpc"
27798
27799         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27800                 error "parallel dio write failed"
27801         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27802
27803         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27804                 error "parallel dio read failed"
27805         diff $DIR/$tfile $DIR/$tfile.2
27806         [[ $? == 0 ]] || error "file diff after parallel dio read"
27807 }
27808 run_test 398j "test parallel dio where stripe size > rpc_size"
27809
27810 test_398k() { #  LU-13798
27811         wait_delete_completed
27812         wait_mds_ost_sync
27813
27814         # 4 stripe file; we will cause out of space on OST0
27815         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27816
27817         # Fill OST0 (if it's not too large)
27818         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27819                    head -n1)
27820         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27821                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27822         fi
27823         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27824         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27825                 error "dd should fill OST0"
27826         stack_trap "rm -f $DIR/$tfile.1"
27827
27828         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27829         err=$?
27830
27831         ls -la $DIR/$tfile
27832         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27833                 error "file is not 0 bytes in size"
27834
27835         # dd above should not succeed, but don't error until here so we can
27836         # get debug info above
27837         [[ $err != 0 ]] ||
27838                 error "parallel dio write with enospc succeeded"
27839         stack_trap "rm -f $DIR/$tfile"
27840 }
27841 run_test 398k "test enospc on first stripe"
27842
27843 test_398l() { #  LU-13798
27844         wait_delete_completed
27845         wait_mds_ost_sync
27846
27847         # 4 stripe file; we will cause out of space on OST0
27848         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27849         # happens on the second i/o chunk we issue
27850         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27851
27852         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27853         stack_trap "rm -f $DIR/$tfile"
27854
27855         # Fill OST0 (if it's not too large)
27856         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27857                    head -n1)
27858         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27859                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27860         fi
27861         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27862         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27863                 error "dd should fill OST0"
27864         stack_trap "rm -f $DIR/$tfile.1"
27865
27866         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27867         err=$?
27868         stack_trap "rm -f $DIR/$tfile.2"
27869
27870         # Check that short write completed as expected
27871         ls -la $DIR/$tfile.2
27872         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27873                 error "file is not 1M in size"
27874
27875         # dd above should not succeed, but don't error until here so we can
27876         # get debug info above
27877         [[ $err != 0 ]] ||
27878                 error "parallel dio write with enospc succeeded"
27879
27880         # Truncate source file to same length as output file and diff them
27881         $TRUNCATE $DIR/$tfile 1048576
27882         diff $DIR/$tfile $DIR/$tfile.2
27883         [[ $? == 0 ]] || error "data incorrect after short write"
27884 }
27885 run_test 398l "test enospc on intermediate stripe/RPC"
27886
27887 test_398m() { #  LU-13798
27888         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27889
27890         # Set up failure on OST0, the first stripe:
27891         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27892         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27893         # OST0 is on ost1, OST1 is on ost2.
27894         # So this fail_val specifies OST0
27895         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27896         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27897
27898         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27899                 error "parallel dio write with failure on first stripe succeeded"
27900         stack_trap "rm -f $DIR/$tfile"
27901         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27902
27903         # Place data in file for read
27904         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27905                 error "parallel dio write failed"
27906
27907         # Fail read on OST0, first stripe
27908         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27909         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27910         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27911                 error "parallel dio read with error on first stripe succeeded"
27912         rm -f $DIR/$tfile.2
27913         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27914
27915         # Switch to testing on OST1, second stripe
27916         # Clear file contents, maintain striping
27917         echo > $DIR/$tfile
27918         # Set up failure on OST1, second stripe:
27919         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27920         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27921
27922         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27923                 error "parallel dio write with failure on second stripe succeeded"
27924         stack_trap "rm -f $DIR/$tfile"
27925         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27926
27927         # Place data in file for read
27928         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27929                 error "parallel dio write failed"
27930
27931         # Fail read on OST1, second stripe
27932         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27933         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27934         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27935                 error "parallel dio read with error on second stripe succeeded"
27936         rm -f $DIR/$tfile.2
27937         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27938 }
27939 run_test 398m "test RPC failures with parallel dio"
27940
27941 # Parallel submission of DIO should not cause problems for append, but it's
27942 # important to verify.
27943 test_398n() { #  LU-13798
27944         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27945
27946         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27947                 error "dd to create source file failed"
27948         stack_trap "rm -f $DIR/$tfile"
27949
27950         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27951                 error "parallel dio write with failure on second stripe succeeded"
27952         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27953         diff $DIR/$tfile $DIR/$tfile.1
27954         [[ $? == 0 ]] || error "data incorrect after append"
27955
27956 }
27957 run_test 398n "test append with parallel DIO"
27958
27959 test_398o() {
27960         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27961 }
27962 run_test 398o "right kms with DIO"
27963
27964 test_398p()
27965 {
27966         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27967         which aiocp || skip_env "no aiocp installed"
27968
27969         local stripe_size=$((1024 * 1024)) #1 MiB
27970         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27971         local file_size=$((25 * stripe_size))
27972
27973         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27974         stack_trap "rm -f $DIR/$tfile*"
27975         # Just a bit bigger than the largest size in the test set below
27976         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27977                 error "buffered i/o to create file failed"
27978
27979         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27980                 $((stripe_size * 4)); do
27981
27982                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27983
27984                 echo "bs: $bs, file_size $file_size"
27985                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27986                         $DIR/$tfile.1 $DIR/$tfile.2 &
27987                 pid_dio1=$!
27988                 # Buffered I/O with similar but not the same block size
27989                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27990                         conv=notrunc &
27991                 pid_bio2=$!
27992                 wait $pid_dio1
27993                 rc1=$?
27994                 wait $pid_bio2
27995                 rc2=$?
27996                 if (( rc1 != 0 )); then
27997                         error "aio copy 1 w/bsize $bs failed: $rc1"
27998                 fi
27999                 if (( rc2 != 0 )); then
28000                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28001                 fi
28002
28003                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28004                         error "size incorrect"
28005                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
28006                         error "files differ, bsize $bs"
28007                 rm -f $DIR/$tfile.2
28008         done
28009 }
28010 run_test 398p "race aio with buffered i/o"
28011
28012 test_398q()
28013 {
28014         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
28015
28016         local stripe_size=$((1024 * 1024)) #1 MiB
28017         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
28018         local file_size=$((25 * stripe_size))
28019
28020         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
28021         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
28022
28023         # Just a bit bigger than the largest size in the test set below
28024         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
28025                 error "buffered i/o to create file failed"
28026
28027         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
28028                 $((stripe_size * 4)); do
28029
28030                 echo "bs: $bs, file_size $file_size"
28031                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
28032                         conv=notrunc oflag=direct iflag=direct &
28033                 pid_dio1=$!
28034                 # Buffered I/O with similar but not the same block size
28035                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28036                         conv=notrunc &
28037                 pid_bio2=$!
28038                 wait $pid_dio1
28039                 rc1=$?
28040                 wait $pid_bio2
28041                 rc2=$?
28042                 if (( rc1 != 0 )); then
28043                         error "dio copy 1 w/bsize $bs failed: $rc1"
28044                 fi
28045                 if (( rc2 != 0 )); then
28046                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28047                 fi
28048
28049                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28050                         error "size incorrect"
28051                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28052                         error "files differ, bsize $bs"
28053         done
28054
28055         rm -f $DIR/$tfile*
28056 }
28057 run_test 398q "race dio with buffered i/o"
28058
28059 test_398r() {
28060         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28061         echo "hello, world" > $DIR/$tfile
28062
28063         cancel_lru_locks osc
28064
28065 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28066         do_facet ost1 $LCTL set_param fail_loc=0x20f
28067         cat $DIR/$tfile > /dev/null && error "cat should fail"
28068         return 0
28069 }
28070 run_test 398r "i/o error on file read"
28071
28072 test_398s() {
28073         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28074                 skip "remote OST"
28075
28076         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28077                 error "mirror create failed"
28078
28079         echo "hello, world" > $DIR/$tfile
28080         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28081
28082         cancel_lru_locks osc
28083
28084 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28085         do_facet ost1 $LCTL set_param fail_loc=0x20f
28086         cat $DIR/$tfile > /dev/null && error "cat should fail"
28087         return 0
28088 }
28089 run_test 398s "i/o error on mirror file read"
28090
28091 test_fake_rw() {
28092         local read_write=$1
28093         if [ "$read_write" = "write" ]; then
28094                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28095         elif [ "$read_write" = "read" ]; then
28096                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28097         else
28098                 error "argument error"
28099         fi
28100
28101         # turn off debug for performance testing
28102         local saved_debug=$($LCTL get_param -n debug)
28103         $LCTL set_param debug=0
28104
28105         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28106
28107         # get ost1 size - $FSNAME-OST0000
28108         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28109         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28110         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28111
28112         if [ "$read_write" = "read" ]; then
28113                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28114         fi
28115
28116         local start_time=$(date +%s.%N)
28117         $dd_cmd bs=1M count=$blocks oflag=sync ||
28118                 error "real dd $read_write error"
28119         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28120
28121         if [ "$read_write" = "write" ]; then
28122                 rm -f $DIR/$tfile
28123         fi
28124
28125         # define OBD_FAIL_OST_FAKE_RW           0x238
28126         do_facet ost1 $LCTL set_param fail_loc=0x238
28127
28128         local start_time=$(date +%s.%N)
28129         $dd_cmd bs=1M count=$blocks oflag=sync ||
28130                 error "fake dd $read_write error"
28131         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28132
28133         if [ "$read_write" = "write" ]; then
28134                 # verify file size
28135                 cancel_lru_locks osc
28136                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28137                         error "$tfile size not $blocks MB"
28138         fi
28139         do_facet ost1 $LCTL set_param fail_loc=0
28140
28141         echo "fake $read_write $duration_fake vs. normal $read_write" \
28142                 "$duration in seconds"
28143         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28144                 error_not_in_vm "fake write is slower"
28145
28146         $LCTL set_param -n debug="$saved_debug"
28147         rm -f $DIR/$tfile
28148 }
28149 test_399a() { # LU-7655 for OST fake write
28150         remote_ost_nodsh && skip "remote OST with nodsh"
28151
28152         test_fake_rw write
28153 }
28154 run_test 399a "fake write should not be slower than normal write"
28155
28156 test_399b() { # LU-8726 for OST fake read
28157         remote_ost_nodsh && skip "remote OST with nodsh"
28158         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28159                 skip_env "ldiskfs only test"
28160         fi
28161
28162         test_fake_rw read
28163 }
28164 run_test 399b "fake read should not be slower than normal read"
28165
28166 test_400a() { # LU-1606, was conf-sanity test_74
28167         if ! which $CC > /dev/null 2>&1; then
28168                 skip_env "$CC is not installed"
28169         fi
28170
28171         local extra_flags=''
28172         local out=$TMP/$tfile
28173         local prefix=/usr/include/lustre
28174         local prog
28175
28176         # Oleg removes .c files in his test rig so test if any c files exist
28177         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28178                 skip_env "Needed .c test files are missing"
28179
28180         if ! [[ -d $prefix ]]; then
28181                 # Assume we're running in tree and fixup the include path.
28182                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28183                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28184                 extra_flags+=" -L$LUSTRE/utils/.libs"
28185         fi
28186
28187         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28188                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28189                         error "client api broken"
28190         done
28191         rm -f $out
28192 }
28193 run_test 400a "Lustre client api program can compile and link"
28194
28195 test_400b() { # LU-1606, LU-5011
28196         local header
28197         local out=$TMP/$tfile
28198         local prefix=/usr/include/linux/lustre
28199
28200         # We use a hard coded prefix so that this test will not fail
28201         # when run in tree. There are headers in lustre/include/lustre/
28202         # that are not packaged (like lustre_idl.h) and have more
28203         # complicated include dependencies (like config.h and lnet/types.h).
28204         # Since this test about correct packaging we just skip them when
28205         # they don't exist (see below) rather than try to fixup cppflags.
28206
28207         if ! which $CC > /dev/null 2>&1; then
28208                 skip_env "$CC is not installed"
28209         fi
28210
28211         for header in $prefix/*.h; do
28212                 if ! [[ -f "$header" ]]; then
28213                         continue
28214                 fi
28215
28216                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28217                         continue # lustre_ioctl.h is internal header
28218                 fi
28219
28220                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28221                         error "cannot compile '$header'"
28222         done
28223         rm -f $out
28224 }
28225 run_test 400b "packaged headers can be compiled"
28226
28227 test_401a() { #LU-7437
28228         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28229         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28230
28231         #count the number of parameters by "list_param -R"
28232         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28233         #count the number of parameters by listing proc files
28234         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28235         echo "proc_dirs='$proc_dirs'"
28236         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28237         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28238                       sort -u | wc -l)
28239
28240         [ $params -eq $procs ] ||
28241                 error "found $params parameters vs. $procs proc files"
28242
28243         # test the list_param -D option only returns directories
28244         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28245         #count the number of parameters by listing proc directories
28246         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28247                 sort -u | wc -l)
28248
28249         [ $params -eq $procs ] ||
28250                 error "found $params parameters vs. $procs proc files"
28251 }
28252 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28253
28254 test_401b() {
28255         # jobid_var may not allow arbitrary values, so use jobid_name
28256         # if available
28257         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28258                 local testname=jobid_name tmp='testing%p'
28259         else
28260                 local testname=jobid_var tmp=testing
28261         fi
28262
28263         local save=$($LCTL get_param -n $testname)
28264
28265         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28266                 error "no error returned when setting bad parameters"
28267
28268         local jobid_new=$($LCTL get_param -n foe $testname baz)
28269         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28270
28271         $LCTL set_param -n fog=bam $testname=$save bat=fog
28272         local jobid_old=$($LCTL get_param -n foe $testname bag)
28273         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28274 }
28275 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28276
28277 test_401c() {
28278         # jobid_var may not allow arbitrary values, so use jobid_name
28279         # if available
28280         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28281                 local testname=jobid_name
28282         else
28283                 local testname=jobid_var
28284         fi
28285
28286         local jobid_var_old=$($LCTL get_param -n $testname)
28287         local jobid_var_new
28288
28289         $LCTL set_param $testname= &&
28290                 error "no error returned for 'set_param a='"
28291
28292         jobid_var_new=$($LCTL get_param -n $testname)
28293         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28294                 error "$testname was changed by setting without value"
28295
28296         $LCTL set_param $testname &&
28297                 error "no error returned for 'set_param a'"
28298
28299         jobid_var_new=$($LCTL get_param -n $testname)
28300         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28301                 error "$testname was changed by setting without value"
28302 }
28303 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28304
28305 test_401d() {
28306         # jobid_var may not allow arbitrary values, so use jobid_name
28307         # if available
28308         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28309                 local testname=jobid_name new_value='foo=bar%p'
28310         else
28311                 local testname=jobid_var new_valuie=foo=bar
28312         fi
28313
28314         local jobid_var_old=$($LCTL get_param -n $testname)
28315         local jobid_var_new
28316
28317         $LCTL set_param $testname=$new_value ||
28318                 error "'set_param a=b' did not accept a value containing '='"
28319
28320         jobid_var_new=$($LCTL get_param -n $testname)
28321         [[ "$jobid_var_new" == "$new_value" ]] ||
28322                 error "'set_param a=b' failed on a value containing '='"
28323
28324         # Reset the $testname to test the other format
28325         $LCTL set_param $testname=$jobid_var_old
28326         jobid_var_new=$($LCTL get_param -n $testname)
28327         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28328                 error "failed to reset $testname"
28329
28330         $LCTL set_param $testname $new_value ||
28331                 error "'set_param a b' did not accept a value containing '='"
28332
28333         jobid_var_new=$($LCTL get_param -n $testname)
28334         [[ "$jobid_var_new" == "$new_value" ]] ||
28335                 error "'set_param a b' failed on a value containing '='"
28336
28337         $LCTL set_param $testname $jobid_var_old
28338         jobid_var_new=$($LCTL get_param -n $testname)
28339         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28340                 error "failed to reset $testname"
28341 }
28342 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28343
28344 test_401e() { # LU-14779
28345         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28346                 error "lctl list_param MGC* failed"
28347         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28348         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28349                 error "lctl get_param lru_size failed"
28350 }
28351 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28352
28353 test_402() {
28354         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28355         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28356                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28357         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28358                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28359                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28360         remote_mds_nodsh && skip "remote MDS with nodsh"
28361
28362         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28363 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28364         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28365         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28366                 echo "Touch failed - OK"
28367 }
28368 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28369
28370 test_403() {
28371         local file1=$DIR/$tfile.1
28372         local file2=$DIR/$tfile.2
28373         local tfile=$TMP/$tfile
28374
28375         rm -f $file1 $file2 $tfile
28376
28377         touch $file1
28378         ln $file1 $file2
28379
28380         # 30 sec OBD_TIMEOUT in ll_getattr()
28381         # right before populating st_nlink
28382         $LCTL set_param fail_loc=0x80001409
28383         stat -c %h $file1 > $tfile &
28384
28385         # create an alias, drop all locks and reclaim the dentry
28386         < $file2
28387         cancel_lru_locks mdc
28388         cancel_lru_locks osc
28389         sysctl -w vm.drop_caches=2
28390
28391         wait
28392
28393         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28394
28395         rm -f $tfile $file1 $file2
28396 }
28397 run_test 403 "i_nlink should not drop to zero due to aliasing"
28398
28399 test_404() { # LU-6601
28400         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28401                 skip "Need server version newer than 2.8.52"
28402         remote_mds_nodsh && skip "remote MDS with nodsh"
28403
28404         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28405                 awk '/osp .*-osc-MDT/ { print $4}')
28406
28407         local osp
28408         for osp in $mosps; do
28409                 echo "Deactivate: " $osp
28410                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28411                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28412                         awk -vp=$osp '$4 == p { print $2 }')
28413                 [ $stat = IN ] || {
28414                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28415                         error "deactivate error"
28416                 }
28417                 echo "Activate: " $osp
28418                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28419                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28420                         awk -vp=$osp '$4 == p { print $2 }')
28421                 [ $stat = UP ] || {
28422                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28423                         error "activate error"
28424                 }
28425         done
28426 }
28427 run_test 404 "validate manual {de}activated works properly for OSPs"
28428
28429 test_405() {
28430         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28431         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28432                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28433                         skip "Layout swap lock is not supported"
28434
28435         check_swap_layouts_support
28436         check_swap_layout_no_dom $DIR
28437
28438         test_mkdir $DIR/$tdir
28439         swap_lock_test -d $DIR/$tdir ||
28440                 error "One layout swap locked test failed"
28441 }
28442 run_test 405 "Various layout swap lock tests"
28443
28444 test_406() {
28445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28446         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28447         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28449         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28450                 skip "Need MDS version at least 2.8.50"
28451
28452         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28453         local test_pool=$TESTNAME
28454
28455         pool_add $test_pool || error "pool_add failed"
28456         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28457                 error "pool_add_targets failed"
28458
28459         save_layout_restore_at_exit $MOUNT
28460
28461         # parent set default stripe count only, child will stripe from both
28462         # parent and fs default
28463         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28464                 error "setstripe $MOUNT failed"
28465         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28466         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28467         for i in $(seq 10); do
28468                 local f=$DIR/$tdir/$tfile.$i
28469                 touch $f || error "touch failed"
28470                 local count=$($LFS getstripe -c $f)
28471                 [ $count -eq $OSTCOUNT ] ||
28472                         error "$f stripe count $count != $OSTCOUNT"
28473                 local offset=$($LFS getstripe -i $f)
28474                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28475                 local size=$($LFS getstripe -S $f)
28476                 [ $size -eq $((def_stripe_size * 2)) ] ||
28477                         error "$f stripe size $size != $((def_stripe_size * 2))"
28478                 local pool=$($LFS getstripe -p $f)
28479                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28480         done
28481
28482         # change fs default striping, delete parent default striping, now child
28483         # will stripe from new fs default striping only
28484         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28485                 error "change $MOUNT default stripe failed"
28486         $LFS setstripe -c 0 $DIR/$tdir ||
28487                 error "delete $tdir default stripe failed"
28488         for i in $(seq 11 20); do
28489                 local f=$DIR/$tdir/$tfile.$i
28490                 touch $f || error "touch $f failed"
28491                 local count=$($LFS getstripe -c $f)
28492                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28493                 local offset=$($LFS getstripe -i $f)
28494                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28495                 local size=$($LFS getstripe -S $f)
28496                 [ $size -eq $def_stripe_size ] ||
28497                         error "$f stripe size $size != $def_stripe_size"
28498                 local pool=$($LFS getstripe -p $f)
28499                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28500         done
28501
28502         unlinkmany $DIR/$tdir/$tfile. 1 20
28503
28504         local f=$DIR/$tdir/$tfile
28505         pool_remove_all_targets $test_pool $f
28506         pool_remove $test_pool $f
28507 }
28508 run_test 406 "DNE support fs default striping"
28509
28510 test_407() {
28511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28512         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28513                 skip "Need MDS version at least 2.8.55"
28514         remote_mds_nodsh && skip "remote MDS with nodsh"
28515
28516         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28517                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28518         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28519                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28520         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28521
28522         #define OBD_FAIL_DT_TXN_STOP    0x2019
28523         for idx in $(seq $MDSCOUNT); do
28524                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28525         done
28526         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28527         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28528                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28529         true
28530 }
28531 run_test 407 "transaction fail should cause operation fail"
28532
28533 test_408() {
28534         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28535
28536         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28537         lctl set_param fail_loc=0x8000040a
28538         # let ll_prepare_partial_page() fail
28539         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28540
28541         rm -f $DIR/$tfile
28542
28543         # create at least 100 unused inodes so that
28544         # shrink_icache_memory(0) should not return 0
28545         touch $DIR/$tfile-{0..100}
28546         rm -f $DIR/$tfile-{0..100}
28547         sync
28548
28549         echo 2 > /proc/sys/vm/drop_caches
28550 }
28551 run_test 408 "drop_caches should not hang due to page leaks"
28552
28553 test_409()
28554 {
28555         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28556
28557         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28558         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28559         touch $DIR/$tdir/guard || error "(2) Fail to create"
28560
28561         local PREFIX=$(str_repeat 'A' 128)
28562         echo "Create 1K hard links start at $(date)"
28563         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28564                 error "(3) Fail to hard link"
28565
28566         echo "Links count should be right although linkEA overflow"
28567         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28568         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28569         [ $linkcount -eq 1001 ] ||
28570                 error "(5) Unexpected hard links count: $linkcount"
28571
28572         echo "List all links start at $(date)"
28573         ls -l $DIR/$tdir/foo > /dev/null ||
28574                 error "(6) Fail to list $DIR/$tdir/foo"
28575
28576         echo "Unlink hard links start at $(date)"
28577         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28578                 error "(7) Fail to unlink"
28579         echo "Unlink hard links finished at $(date)"
28580 }
28581 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28582
28583 test_410()
28584 {
28585         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28586                 skip "Need client version at least 2.9.59"
28587
28588         # Create a file, and stat it from the kernel
28589         local testfile=$DIR/$tfile
28590         touch $testfile
28591
28592         local run_id=$RANDOM
28593         local my_ino=$(stat --format "%i" $testfile)
28594
28595         # Try to insert the module.
28596         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28597                 error "load_module failed"
28598
28599         # Anything but success is a test failure
28600         dmesg | grep -q \
28601             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28602             error "no inode match"
28603
28604         # Remove the test module
28605         rmmod -v kinode ||
28606                 error "rmmod failed (may trigger a failure in a later test)"
28607 }
28608 run_test 410 "Test inode number returned from kernel thread"
28609
28610 cleanup_test411_cgroup() {
28611         trap 0
28612         cat $1/memory.stat
28613         rmdir "$1"
28614 }
28615
28616 test_411a() {
28617         local cg_basedir=/sys/fs/cgroup/memory
28618         # LU-9966
28619         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28620                 skip "no setup for cgroup"
28621
28622         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28623                 error "test file creation failed"
28624         cancel_lru_locks osc
28625
28626         # Create a very small memory cgroup to force a slab allocation error
28627         local cgdir=$cg_basedir/osc_slab_alloc
28628         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28629         trap "cleanup_test411_cgroup $cgdir" EXIT
28630         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28631         echo 1M > $cgdir/memory.limit_in_bytes
28632
28633         # Should not LBUG, just be killed by oom-killer
28634         # dd will return 0 even allocation failure in some environment.
28635         # So don't check return value
28636         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28637         cleanup_test411_cgroup $cgdir
28638
28639         return 0
28640 }
28641 run_test 411a "Slab allocation error with cgroup does not LBUG"
28642
28643 test_411b() {
28644         local cg_basedir=/sys/fs/cgroup/memory
28645         # LU-9966
28646         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28647                 skip "no setup for cgroup"
28648         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28649         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28650         # limit, so we have 384M in cgroup
28651         # (arm) this seems to hit OOM more often than x86, so 1024M
28652         if [[ $(uname -m) = aarch64 ]]; then
28653                 local memlimit_mb=1024
28654         else
28655                 local memlimit_mb=384
28656         fi
28657
28658         # Create a cgroup and set memory limit
28659         # (tfile is used as an easy way to get a recognizable cgroup name)
28660         local cgdir=$cg_basedir/$tfile
28661         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28662         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28663         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28664
28665         echo "writing first file"
28666         # Write a file 4x the memory limit in size
28667         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28668                 error "(1) failed to write successfully"
28669
28670         sync
28671         cancel_lru_locks osc
28672
28673         rm -f $DIR/$tfile
28674         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28675
28676         # Try writing at a larger block size
28677         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28678         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28679         # need *some* memory to do IO in)
28680         echo "writing at larger block size"
28681         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28682                 error "(3) failed to write successfully"
28683
28684         sync
28685         cancel_lru_locks osc
28686         rm -f $DIR/$tfile
28687         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28688
28689         # Try writing multiple files at once
28690         echo "writing multiple files"
28691         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28692         local pid1=$!
28693         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28694         local pid2=$!
28695         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28696         local pid3=$!
28697         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28698         local pid4=$!
28699
28700         wait $pid1
28701         local rc1=$?
28702         wait $pid2
28703         local rc2=$?
28704         wait $pid3
28705         local rc3=$?
28706         wait $pid4
28707         local rc4=$?
28708         if (( rc1 != 0)); then
28709                 error "error $rc1 writing to file from $pid1"
28710         fi
28711         if (( rc2 != 0)); then
28712                 error "error $rc2 writing to file from $pid2"
28713         fi
28714         if (( rc3 != 0)); then
28715                 error "error $rc3 writing to file from $pid3"
28716         fi
28717         if (( rc4 != 0)); then
28718                 error "error $rc4 writing to file from $pid4"
28719         fi
28720
28721         sync
28722         cancel_lru_locks osc
28723
28724         # These files can be large-ish (~1 GiB total), so delete them rather
28725         # than leave for later cleanup
28726         rm -f $DIR/$tfile.*
28727         return 0
28728 }
28729 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28730
28731 test_412() {
28732         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28733         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28734                 skip "Need server version at least 2.10.55"
28735
28736         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28737                 error "mkdir failed"
28738         $LFS getdirstripe $DIR/$tdir
28739         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28740         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28741                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28742         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28743         [ $stripe_count -eq 2 ] ||
28744                 error "expect 2 get $stripe_count"
28745
28746         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28747
28748         local index
28749         local index2
28750
28751         # subdirs should be on the same MDT as parent
28752         for i in $(seq 0 $((MDSCOUNT - 1))); do
28753                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28754                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28755                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28756                 (( index == i )) || error "mdt$i/sub on MDT$index"
28757         done
28758
28759         # stripe offset -1, ditto
28760         for i in {1..10}; do
28761                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28762                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28763                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28764                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28765                 (( index == index2 )) ||
28766                         error "qos$i on MDT$index, sub on MDT$index2"
28767         done
28768
28769         local testdir=$DIR/$tdir/inherit
28770
28771         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28772         # inherit 2 levels
28773         for i in 1 2; do
28774                 testdir=$testdir/s$i
28775                 mkdir $testdir || error "mkdir $testdir failed"
28776                 index=$($LFS getstripe -m $testdir)
28777                 (( index == 1 )) ||
28778                         error "$testdir on MDT$index"
28779         done
28780
28781         # not inherit any more
28782         testdir=$testdir/s3
28783         mkdir $testdir || error "mkdir $testdir failed"
28784         getfattr -d -m dmv $testdir | grep dmv &&
28785                 error "default LMV set on $testdir" || true
28786 }
28787 run_test 412 "mkdir on specific MDTs"
28788
28789 TEST413_COUNT=${TEST413_COUNT:-200}
28790
28791 #
28792 # set_maxage() is used by test_413 only.
28793 # This is a helper function to set maxage. Does not return any value.
28794 # Input: maxage to set
28795 #
28796 set_maxage() {
28797         local lmv_qos_maxage
28798         local lod_qos_maxage
28799         local new_maxage=$1
28800
28801         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28802         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28803         stack_trap "$LCTL set_param \
28804                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28805         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28806                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28807         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28808                 lod.*.mdt_qos_maxage=$new_maxage
28809         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28810                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28811 }
28812
28813 generate_uneven_mdts() {
28814         local threshold=$1
28815         local ffree
28816         local bavail
28817         local max
28818         local min
28819         local max_index
28820         local min_index
28821         local tmp
28822         local i
28823
28824         echo
28825         echo "Check for uneven MDTs: "
28826
28827         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28828         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28829         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28830
28831         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28832         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28833         max_index=0
28834         min_index=0
28835         for ((i = 1; i < ${#ffree[@]}; i++)); do
28836                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28837                 if [ $tmp -gt $max ]; then
28838                         max=$tmp
28839                         max_index=$i
28840                 fi
28841                 if [ $tmp -lt $min ]; then
28842                         min=$tmp
28843                         min_index=$i
28844                 fi
28845         done
28846
28847         (( min > 0 )) || skip "low space on MDT$min_index"
28848         (( ${ffree[min_index]} > 0 )) ||
28849                 skip "no free files on MDT$min_index"
28850         (( ${ffree[min_index]} < 10000000 )) ||
28851                 skip "too many free files on MDT$min_index"
28852
28853         # Check if we need to generate uneven MDTs
28854         local diff=$(((max - min) * 100 / min))
28855         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28856         local testdir # individual folder within $testdirp
28857         local start
28858         local cmd
28859
28860         # fallocate is faster to consume space on MDT, if available
28861         if check_fallocate_supported mds$((min_index + 1)); then
28862                 cmd="fallocate -l 128K "
28863         else
28864                 cmd="dd if=/dev/zero bs=128K count=1 of="
28865         fi
28866
28867         echo "using cmd $cmd"
28868         for (( i = 0; diff < threshold; i++ )); do
28869                 testdir=${testdirp}/$i
28870                 [ -d $testdir ] && continue
28871
28872                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28873
28874                 mkdir -p $testdirp
28875                 # generate uneven MDTs, create till $threshold% diff
28876                 echo -n "weight diff=$diff% must be > $threshold% ..."
28877                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28878                 $LFS mkdir -i $min_index $testdir ||
28879                         error "mkdir $testdir failed"
28880                 $LFS setstripe -E 1M -L mdt $testdir ||
28881                         error "setstripe $testdir failed"
28882                 start=$SECONDS
28883                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28884                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28885                 done
28886                 sync; sleep 1; sync
28887
28888                 # wait for QOS to update
28889                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28890
28891                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28892                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28893                 max=$(((${ffree[max_index]} >> 8) *
28894                         (${bavail[max_index]} * bsize >> 16)))
28895                 min=$(((${ffree[min_index]} >> 8) *
28896                         (${bavail[min_index]} * bsize >> 16)))
28897                 (( min > 0 )) || skip "low space on MDT$min_index"
28898                 diff=$(((max - min) * 100 / min))
28899         done
28900
28901         echo "MDT filesfree available: ${ffree[*]}"
28902         echo "MDT blocks available: ${bavail[*]}"
28903         echo "weight diff=$diff%"
28904 }
28905
28906 test_qos_mkdir() {
28907         local mkdir_cmd=$1
28908         local stripe_count=$2
28909         local mdts=$(comma_list $(mdts_nodes))
28910
28911         local testdir
28912         local lmv_qos_prio_free
28913         local lmv_qos_threshold_rr
28914         local lod_qos_prio_free
28915         local lod_qos_threshold_rr
28916         local total
28917         local count
28918         local i
28919
28920         # @total is total directories created if it's testing plain
28921         # directories, otherwise it's total stripe object count for
28922         # striped directories test.
28923         # remote/striped directory unlinking is slow on zfs and may
28924         # timeout, test with fewer directories
28925         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28926
28927         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28928         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28929         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28930                 head -n1)
28931         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28932         stack_trap "$LCTL set_param \
28933                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28934         stack_trap "$LCTL set_param \
28935                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28936
28937         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28938                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28939         lod_qos_prio_free=${lod_qos_prio_free%%%}
28940         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28941                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28942         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28943         stack_trap "do_nodes $mdts $LCTL set_param \
28944                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28945         stack_trap "do_nodes $mdts $LCTL set_param \
28946                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28947
28948         # decrease statfs age, so that it can be updated in time
28949         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28950         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28951
28952         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28953         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28954
28955         testdir=$DIR/$tdir-s$stripe_count/rr
28956
28957         local stripe_index=$($LFS getstripe -m $testdir)
28958         local test_mkdir_rr=true
28959
28960         getfattr -d -m dmv -e hex $testdir | grep dmv
28961         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28962                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28963                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28964                         test_mkdir_rr=false
28965         fi
28966
28967         echo
28968         $test_mkdir_rr &&
28969                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28970                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28971
28972         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28973         for (( i = 0; i < total / stripe_count; i++ )); do
28974                 eval $mkdir_cmd $testdir/subdir$i ||
28975                         error "$mkdir_cmd subdir$i failed"
28976         done
28977
28978         for (( i = 0; i < $MDSCOUNT; i++ )); do
28979                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28980                 echo "$count directories created on MDT$i"
28981                 if $test_mkdir_rr; then
28982                         (( count == total / stripe_count / MDSCOUNT )) ||
28983                                 error "subdirs are not evenly distributed"
28984                 elif (( i == stripe_index )); then
28985                         (( count == total / stripe_count )) ||
28986                                 error "$count subdirs created on MDT$i"
28987                 else
28988                         (( count == 0 )) ||
28989                                 error "$count subdirs created on MDT$i"
28990                 fi
28991
28992                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28993                         count=$($LFS getdirstripe $testdir/* |
28994                                 grep -c -P "^\s+$i\t")
28995                         echo "$count stripes created on MDT$i"
28996                         # deviation should < 5% of average
28997                         delta=$((count - total / MDSCOUNT))
28998                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28999                                 error "stripes are not evenly distributed"
29000                 fi
29001         done
29002
29003         echo
29004         echo "Check for uneven MDTs: "
29005
29006         local ffree
29007         local bavail
29008         local max
29009         local min
29010         local max_index
29011         local min_index
29012         local tmp
29013
29014         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29015         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29016         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29017
29018         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29019         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29020         max_index=0
29021         min_index=0
29022         for ((i = 1; i < ${#ffree[@]}; i++)); do
29023                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29024                 if [ $tmp -gt $max ]; then
29025                         max=$tmp
29026                         max_index=$i
29027                 fi
29028                 if [ $tmp -lt $min ]; then
29029                         min=$tmp
29030                         min_index=$i
29031                 fi
29032         done
29033         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29034
29035         (( min > 0 )) || skip "low space on MDT$min_index"
29036         (( ${ffree[min_index]} < 10000000 )) ||
29037                 skip "too many free files on MDT$min_index"
29038
29039         generate_uneven_mdts 120
29040
29041         echo "MDT filesfree available: ${ffree[*]}"
29042         echo "MDT blocks available: ${bavail[*]}"
29043         echo "weight diff=$(((max - min) * 100 / min))%"
29044         echo
29045         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29046
29047         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29048         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29049         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29050         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29051
29052         sleep 1
29053
29054         testdir=$DIR/$tdir-s$stripe_count/qos
29055
29056         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29057         for (( i = 0; i < total / stripe_count; i++ )); do
29058                 eval $mkdir_cmd $testdir/subdir$i ||
29059                         error "$mkdir_cmd subdir$i failed"
29060         done
29061
29062         max=0
29063         for (( i = 0; i < $MDSCOUNT; i++ )); do
29064                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29065                 (( count > max )) && max=$count
29066                 echo "$count directories created on MDT$i : curmax=$max"
29067         done
29068
29069         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29070
29071         # D-value should > 10% of average
29072         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29073                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29074
29075         # ditto for stripes
29076         if (( stripe_count > 1 )); then
29077                 max=0
29078                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29079                         count=$($LFS getdirstripe $testdir/* |
29080                                 grep -c -P "^\s+$i\t")
29081                         (( count > max )) && max=$count
29082                         echo "$count stripes created on MDT$i"
29083                 done
29084
29085                 min=$($LFS getdirstripe $testdir/* |
29086                         grep -c -P "^\s+$min_index\t")
29087                 (( max - min > total / MDSCOUNT / 10 )) ||
29088                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29089         fi
29090 }
29091
29092 most_full_mdt() {
29093         local ffree
29094         local bavail
29095         local bsize
29096         local min
29097         local min_index
29098         local tmp
29099
29100         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29101         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29102         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29103
29104         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29105         min_index=0
29106         for ((i = 1; i < ${#ffree[@]}; i++)); do
29107                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29108                 (( tmp < min )) && min=$tmp && min_index=$i
29109         done
29110
29111         echo -n $min_index
29112 }
29113
29114 test_413a() {
29115         [ $MDSCOUNT -lt 2 ] &&
29116                 skip "We need at least 2 MDTs for this test"
29117
29118         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29119                 skip "Need server version at least 2.12.52"
29120
29121         local stripe_max=$((MDSCOUNT - 1))
29122         local stripe_count
29123
29124         # let caller set maxage for latest result
29125         set_maxage 1
29126
29127         # fill MDT unevenly
29128         generate_uneven_mdts 120
29129
29130         # test 4-stripe directory at most, otherwise it's too slow
29131         # We are being very defensive. Although Autotest uses 4 MDTs.
29132         # We make sure stripe_max does not go over 4.
29133         (( stripe_max > 4 )) && stripe_max=4
29134         # unlinking striped directory is slow on zfs, and may timeout, only test
29135         # plain directory
29136         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29137         for stripe_count in $(seq 1 $stripe_max); do
29138                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29139                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29140                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29141                         error "mkdir failed"
29142                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29143         done
29144 }
29145 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29146
29147 test_413b() {
29148         [ $MDSCOUNT -lt 2 ] &&
29149                 skip "We need at least 2 MDTs for this test"
29150
29151         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29152                 skip "Need server version at least 2.12.52"
29153
29154         local stripe_max=$((MDSCOUNT - 1))
29155         local testdir
29156         local stripe_count
29157
29158         # let caller set maxage for latest result
29159         set_maxage 1
29160
29161         # fill MDT unevenly
29162         generate_uneven_mdts 120
29163
29164         # test 4-stripe directory at most, otherwise it's too slow
29165         # We are being very defensive. Although Autotest uses 4 MDTs.
29166         # We make sure stripe_max does not go over 4.
29167         (( stripe_max > 4 )) && stripe_max=4
29168         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29169         for stripe_count in $(seq 1 $stripe_max); do
29170                 testdir=$DIR/$tdir-s$stripe_count
29171                 mkdir $testdir || error "mkdir $testdir failed"
29172                 mkdir $testdir/rr || error "mkdir rr failed"
29173                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29174                         error "mkdir qos failed"
29175                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29176                         $testdir/rr || error "setdirstripe rr failed"
29177                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29178                         error "setdirstripe failed"
29179                 test_qos_mkdir "mkdir" $stripe_count
29180         done
29181 }
29182 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29183
29184 test_413c() {
29185         (( $MDSCOUNT >= 2 )) ||
29186                 skip "We need at least 2 MDTs for this test"
29187
29188         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29189                 skip "Need server version at least 2.14.51"
29190
29191         local testdir
29192         local inherit
29193         local inherit_rr
29194         local lmv_qos_maxage
29195         local lod_qos_maxage
29196
29197         # let caller set maxage for latest result
29198         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29199         $LCTL set_param lmv.*.qos_maxage=1
29200         stack_trap "$LCTL set_param \
29201                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29202         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29203                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29204         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29205                 lod.*.mdt_qos_maxage=1
29206         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29207                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29208
29209         # fill MDT unevenly
29210         generate_uneven_mdts 120
29211
29212         testdir=$DIR/${tdir}-s1
29213         mkdir $testdir || error "mkdir $testdir failed"
29214         mkdir $testdir/rr || error "mkdir rr failed"
29215         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29216         # default max_inherit is -1, default max_inherit_rr is 0
29217         $LFS setdirstripe -D -c 1 $testdir/rr ||
29218                 error "setdirstripe rr failed"
29219         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29220                 error "setdirstripe qos failed"
29221         test_qos_mkdir "mkdir" 1
29222
29223         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29224         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29225         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29226         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29227         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29228
29229         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29230         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29231         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29232         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29233         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29234         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29235         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29236                 error "level2 shouldn't have default LMV" || true
29237 }
29238 run_test 413c "mkdir with default LMV max inherit rr"
29239
29240 test_413d() {
29241         (( MDSCOUNT >= 2 )) ||
29242                 skip "We need at least 2 MDTs for this test"
29243
29244         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29245                 skip "Need server version at least 2.14.51"
29246
29247         local lmv_qos_threshold_rr
29248
29249         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29250                 head -n1)
29251         stack_trap "$LCTL set_param \
29252                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29253
29254         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29255         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29256         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29257                 error "$tdir shouldn't have default LMV"
29258         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29259                 error "mkdir sub failed"
29260
29261         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29262
29263         (( count == 100 )) || error "$count subdirs on MDT0"
29264 }
29265 run_test 413d "inherit ROOT default LMV"
29266
29267 test_413e() {
29268         (( MDSCOUNT >= 2 )) ||
29269                 skip "We need at least 2 MDTs for this test"
29270         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29271                 skip "Need server version at least 2.14.55"
29272
29273         local testdir=$DIR/$tdir
29274         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29275         local max_inherit
29276         local sub_max_inherit
29277
29278         mkdir -p $testdir || error "failed to create $testdir"
29279
29280         # set default max-inherit to -1 if stripe count is 0 or 1
29281         $LFS setdirstripe -D -c 1 $testdir ||
29282                 error "failed to set default LMV"
29283         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29284         (( max_inherit == -1 )) ||
29285                 error "wrong max_inherit value $max_inherit"
29286
29287         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29288         $LFS setdirstripe -D -c -1 $testdir ||
29289                 error "failed to set default LMV"
29290         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29291         (( max_inherit > 0 )) ||
29292                 error "wrong max_inherit value $max_inherit"
29293
29294         # and the subdir will decrease the max_inherit by 1
29295         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29296         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29297         (( sub_max_inherit == max_inherit - 1)) ||
29298                 error "wrong max-inherit of subdir $sub_max_inherit"
29299
29300         # check specified --max-inherit and warning message
29301         stack_trap "rm -f $tmpfile"
29302         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29303                 error "failed to set default LMV"
29304         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29305         (( max_inherit == -1 )) ||
29306                 error "wrong max_inherit value $max_inherit"
29307
29308         # check the warning messages
29309         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29310                 error "failed to detect warning string"
29311         fi
29312 }
29313 run_test 413e "check default max-inherit value"
29314
29315 test_fs_dmv_inherit()
29316 {
29317         local testdir=$DIR/$tdir
29318
29319         local count
29320         local inherit
29321         local inherit_rr
29322
29323         for i in 1 2; do
29324                 mkdir $testdir || error "mkdir $testdir failed"
29325                 count=$($LFS getdirstripe -D -c $testdir)
29326                 (( count == 1 )) ||
29327                         error "$testdir default LMV count mismatch $count != 1"
29328                 inherit=$($LFS getdirstripe -D -X $testdir)
29329                 (( inherit == 3 - i )) ||
29330                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29331                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29332                 (( inherit_rr == 3 - i )) ||
29333                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29334                 testdir=$testdir/sub
29335         done
29336
29337         mkdir $testdir || error "mkdir $testdir failed"
29338         count=$($LFS getdirstripe -D -c $testdir)
29339         (( count == 0 )) ||
29340                 error "$testdir default LMV count not zero: $count"
29341 }
29342
29343 test_413f() {
29344         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29345
29346         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29347                 skip "Need server version at least 2.14.55"
29348
29349         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29350                 error "dump $DIR default LMV failed"
29351         stack_trap "setfattr --restore=$TMP/dmv.ea"
29352
29353         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29354                 error "set $DIR default LMV failed"
29355
29356         test_fs_dmv_inherit
29357 }
29358 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29359
29360 test_413g() {
29361         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29362
29363         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29364         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29365                 error "dump $DIR default LMV failed"
29366         stack_trap "setfattr --restore=$TMP/dmv.ea"
29367
29368         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29369                 error "set $DIR default LMV failed"
29370
29371         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29372                 error "mount $MOUNT2 failed"
29373         stack_trap "umount_client $MOUNT2"
29374
29375         local saved_DIR=$DIR
29376
29377         export DIR=$MOUNT2
29378
29379         stack_trap "export DIR=$saved_DIR"
29380
29381         # first check filesystem-wide default LMV inheritance
29382         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29383
29384         # then check subdirs are spread to all MDTs
29385         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29386
29387         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29388
29389         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29390 }
29391 run_test 413g "enforce ROOT default LMV on subdir mount"
29392
29393 test_413h() {
29394         (( MDSCOUNT >= 2 )) ||
29395                 skip "We need at least 2 MDTs for this test"
29396
29397         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29398                 skip "Need server version at least 2.15.50.6"
29399
29400         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29401
29402         stack_trap "$LCTL set_param \
29403                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29404         $LCTL set_param lmv.*.qos_maxage=1
29405
29406         local depth=5
29407         local rr_depth=4
29408         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29409         local count=$((MDSCOUNT * 20))
29410
29411         generate_uneven_mdts 50
29412
29413         mkdir -p $dir || error "mkdir $dir failed"
29414         stack_trap "rm -rf $dir"
29415         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29416                 --max-inherit-rr=$rr_depth $dir
29417
29418         for ((d=0; d < depth + 2; d++)); do
29419                 log "dir=$dir:"
29420                 for ((sub=0; sub < count; sub++)); do
29421                         mkdir $dir/d$sub
29422                 done
29423                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29424                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29425                 # subdirs within $rr_depth should be created round-robin
29426                 if (( d < rr_depth )); then
29427                         (( ${num[0]} != count )) ||
29428                                 error "all objects created on MDT ${num[1]}"
29429                 fi
29430
29431                 dir=$dir/d0
29432         done
29433 }
29434 run_test 413h "don't stick to parent for round-robin dirs"
29435
29436 test_413i() {
29437         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29438
29439         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29440                 skip "Need server version at least 2.14.55"
29441
29442         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29443                 error "dump $DIR default LMV failed"
29444         stack_trap "setfattr --restore=$TMP/dmv.ea"
29445
29446         local testdir=$DIR/$tdir
29447         local def_max_rr=1
29448         local def_max=3
29449         local count
29450
29451         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29452                 --max-inherit-rr=$def_max_rr $DIR ||
29453                 error "set $DIR default LMV failed"
29454
29455         for i in $(seq 2 3); do
29456                 def_max=$((def_max - 1))
29457                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29458
29459                 mkdir $testdir
29460                 # RR is decremented and keeps zeroed once exhausted
29461                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29462                 (( count == def_max_rr )) ||
29463                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29464
29465                 # max-inherit is decremented
29466                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29467                 (( count == def_max )) ||
29468                         error_noexit "$testdir: max-inherit $count != $def_max"
29469
29470                 testdir=$testdir/d$i
29471         done
29472
29473         # d3 is the last inherited from ROOT, no inheritance anymore
29474         # i.e. no the default layout anymore
29475         mkdir -p $testdir/d4/d5
29476         count=$($LFS getdirstripe -D --max-inherit $testdir)
29477         (( count == -1 )) ||
29478                 error_noexit "$testdir: max-inherit $count != -1"
29479
29480         local p_count=$($LFS getdirstripe -i $testdir)
29481
29482         for i in $(seq 4 5); do
29483                 testdir=$testdir/d$i
29484
29485                 # the root default layout is not applied once exhausted
29486                 count=$($LFS getdirstripe -i $testdir)
29487                 (( count == p_count )) ||
29488                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29489         done
29490
29491         $LFS setdirstripe -i 0 $DIR/d2
29492         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29493         (( count == -1 )) ||
29494                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29495 }
29496 run_test 413i "check default layout inheritance"
29497
29498 test_413j()
29499 {
29500         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29501
29502         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29503         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29504                 error "setdirstripe $tdir failed"
29505
29506         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29507                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29508
29509         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29510         # setfattr dmv calls setdirstripe -D
29511         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29512                 error "setfattr sub failed"
29513         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29514                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29515
29516         [ $value == $value2 ] || error "dmv mismatch"
29517
29518         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29519
29520         # do not allow remove dmv by setfattr -x
29521         do_nodes $(comma_list $(mdts_nodes)) \
29522                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29523         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29524         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29525
29526         # allow remove dmv by setfattr -x
29527         do_nodes $(comma_list $(mdts_nodes)) \
29528                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29529         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29530         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29531         do_nodes $(comma_list $(mdts_nodes)) \
29532                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29533 }
29534 run_test 413j "set default LMV by setxattr"
29535
29536 test_413k() {
29537         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29538                 skip "Need server version at least 2.15.60"
29539
29540         local index1
29541         local index2
29542         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29543         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29544         local prefixes="abc:123:foo bar"
29545
29546         # add prefixes
29547         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29548         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29549
29550         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29551         index1=$($LFS getstripe -m $DIR/$tdir)
29552         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29553                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29554                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29555                 ((index1 == index2)) ||
29556                         error "$tdir on MDT$index1, $dname on MDT$index2"
29557         done
29558
29559         # remove prefixes
29560         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29561
29562         # total prefixes length > PAGE_SIZE can be printed correctly
29563         for c in {a..z}; do
29564                 prefixes=$(str_repeat $c 255)
29565                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29566         done
29567         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29568         ((count2 == count + 26)) ||
29569                 error "prefixes count $count2 != $((count + 26))"
29570 }
29571 run_test 413k "QoS mkdir exclude prefixes"
29572
29573 test_413z() {
29574         local pids=""
29575         local subdir
29576         local pid
29577
29578         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29579                 unlinkmany $subdir/f. $TEST413_COUNT &
29580                 pids="$pids $!"
29581         done
29582
29583         for pid in $pids; do
29584                 wait $pid
29585         done
29586
29587         true
29588 }
29589 run_test 413z "413 test cleanup"
29590
29591 test_414() {
29592 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29593         $LCTL set_param fail_loc=0x80000521
29594         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29595         rm -f $DIR/$tfile
29596         # This error path has sometimes left inflight requests dangling, so
29597         # test for this by remounting the client (umount will hang if there's
29598         # a dangling request)
29599         umount_client $MOUNT
29600         mount_client $MOUNT
29601 }
29602 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29603
29604 test_415() {
29605         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29606         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29607                 skip "Need server version at least 2.11.52"
29608
29609         # LU-11102
29610         local total=500
29611         local max=120
29612
29613         # this test may be slow on ZFS
29614         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29615
29616         # though this test is designed for striped directory, let's test normal
29617         # directory too since lock is always saved as CoS lock.
29618         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29619         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29620         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29621         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29622         wait_delete_completed_mds
29623
29624         # run a loop without concurrent touch to measure rename duration.
29625         # only for test debug/robustness, NOT part of COS functional test.
29626         local start_time=$SECONDS
29627         for ((i = 0; i < total; i++)); do
29628                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29629                         > /dev/null
29630         done
29631         local baseline=$((SECONDS - start_time))
29632         echo "rename $total files without 'touch' took $baseline sec"
29633
29634         (
29635                 while true; do
29636                         touch $DIR/$tdir
29637                 done
29638         ) &
29639         local setattr_pid=$!
29640
29641         # rename files back to original name so unlinkmany works
29642         start_time=$SECONDS
29643         for ((i = 0; i < total; i++)); do
29644                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29645                         > /dev/null
29646         done
29647         local duration=$((SECONDS - start_time))
29648
29649         kill -9 $setattr_pid
29650
29651         echo "rename $total files with 'touch' took $duration sec"
29652         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29653         (( duration <= max )) ||
29654                 error_not_in_vm "rename took $duration > $max sec"
29655 }
29656 run_test 415 "lock revoke is not missing"
29657
29658 test_416() {
29659         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29660                 skip "Need server version at least 2.11.55"
29661
29662         # define OBD_FAIL_OSD_TXN_START    0x19a
29663         do_facet mds1 lctl set_param fail_loc=0x19a
29664
29665         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29666
29667         true
29668 }
29669 run_test 416 "transaction start failure won't cause system hung"
29670
29671 cleanup_417() {
29672         trap 0
29673         do_nodes $(comma_list $(mdts_nodes)) \
29674                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29675         do_nodes $(comma_list $(mdts_nodes)) \
29676                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29677         do_nodes $(comma_list $(mdts_nodes)) \
29678                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29679 }
29680
29681 test_417() {
29682         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29683         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29684                 skip "Need MDS version at least 2.11.56"
29685
29686         trap cleanup_417 RETURN EXIT
29687
29688         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29689         do_nodes $(comma_list $(mdts_nodes)) \
29690                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29691         $LFS migrate -m 0 $DIR/$tdir.1 &&
29692                 error "migrate dir $tdir.1 should fail"
29693
29694         do_nodes $(comma_list $(mdts_nodes)) \
29695                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29696         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29697                 error "create remote dir $tdir.2 should fail"
29698
29699         do_nodes $(comma_list $(mdts_nodes)) \
29700                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29701         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29702                 error "create striped dir $tdir.3 should fail"
29703         true
29704 }
29705 run_test 417 "disable remote dir, striped dir and dir migration"
29706
29707 # Checks that the outputs of df [-i] and lfs df [-i] match
29708 #
29709 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29710 check_lfs_df() {
29711         local dir=$2
29712         local inodes
29713         local df_out
29714         local lfs_df_out
29715         local count
29716         local passed=false
29717
29718         # blocks or inodes
29719         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29720
29721         for count in {1..100}; do
29722                 do_nodes "$CLIENTS" \
29723                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29724                 sync; sleep 0.2
29725
29726                 # read the lines of interest
29727                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29728                         error "df $inodes $dir | tail -n +2 failed"
29729                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29730                         error "lfs df $inodes $dir | grep summary: failed"
29731
29732                 # skip first substrings of each output as they are different
29733                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29734                 # compare the two outputs
29735                 passed=true
29736                 #  skip "available" on MDT until LU-13997 is fixed.
29737                 #for i in {1..5}; do
29738                 for i in 1 2 4 5; do
29739                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29740                 done
29741                 $passed && break
29742         done
29743
29744         if ! $passed; then
29745                 df -P $inodes $dir
29746                 echo
29747                 lfs df $inodes $dir
29748                 error "df and lfs df $1 output mismatch: "      \
29749                       "df ${inodes}: ${df_out[*]}, "            \
29750                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29751         fi
29752 }
29753
29754 test_418() {
29755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29756
29757         local dir=$DIR/$tdir
29758         local numfiles=$((RANDOM % 4096 + 2))
29759         local numblocks=$((RANDOM % 256 + 1))
29760
29761         wait_delete_completed
29762         test_mkdir $dir
29763
29764         # check block output
29765         check_lfs_df blocks $dir
29766         # check inode output
29767         check_lfs_df inodes $dir
29768
29769         # create a single file and retest
29770         echo "Creating a single file and testing"
29771         createmany -o $dir/$tfile- 1 &>/dev/null ||
29772                 error "creating 1 file in $dir failed"
29773         check_lfs_df blocks $dir
29774         check_lfs_df inodes $dir
29775
29776         # create a random number of files
29777         echo "Creating $((numfiles - 1)) files and testing"
29778         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29779                 error "creating $((numfiles - 1)) files in $dir failed"
29780
29781         # write a random number of blocks to the first test file
29782         echo "Writing $numblocks 4K blocks and testing"
29783         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29784                 count=$numblocks &>/dev/null ||
29785                 error "dd to $dir/${tfile}-0 failed"
29786
29787         # retest
29788         check_lfs_df blocks $dir
29789         check_lfs_df inodes $dir
29790
29791         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29792                 error "unlinking $numfiles files in $dir failed"
29793 }
29794 run_test 418 "df and lfs df outputs match"
29795
29796 test_419()
29797 {
29798         local dir=$DIR/$tdir
29799
29800         mkdir -p $dir
29801         touch $dir/file
29802
29803         cancel_lru_locks mdc
29804
29805         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29806         $LCTL set_param fail_loc=0x1410
29807         cat $dir/file
29808         $LCTL set_param fail_loc=0
29809         rm -rf $dir
29810 }
29811 run_test 419 "Verify open file by name doesn't crash kernel"
29812
29813 test_420()
29814 {
29815         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29816                 skip "Need MDS version at least 2.12.53"
29817
29818         local SAVE_UMASK=$(umask)
29819         local dir=$DIR/$tdir
29820         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29821
29822         mkdir -p $dir
29823         umask 0000
29824         mkdir -m03777 $dir/testdir
29825         ls -dn $dir/testdir
29826         # Need to remove trailing '.' when SELinux is enabled
29827         local dirperms=$(ls -dn $dir/testdir |
29828                          awk '{ sub(/\.$/, "", $1); print $1}')
29829         [ $dirperms == "drwxrwsrwt" ] ||
29830                 error "incorrect perms on $dir/testdir"
29831
29832         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29833                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29834         ls -n $dir/testdir/testfile
29835         local fileperms=$(ls -n $dir/testdir/testfile |
29836                           awk '{ sub(/\.$/, "", $1); print $1}')
29837         [ $fileperms == "-rwxr-xr-x" ] ||
29838                 error "incorrect perms on $dir/testdir/testfile"
29839
29840         umask $SAVE_UMASK
29841 }
29842 run_test 420 "clear SGID bit on non-directories for non-members"
29843
29844 test_421a() {
29845         local cnt
29846         local fid1
29847         local fid2
29848
29849         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29850                 skip "Need MDS version at least 2.12.54"
29851
29852         test_mkdir $DIR/$tdir
29853         createmany -o $DIR/$tdir/f 3
29854         cnt=$(ls -1 $DIR/$tdir | wc -l)
29855         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29856
29857         fid1=$(lfs path2fid $DIR/$tdir/f1)
29858         fid2=$(lfs path2fid $DIR/$tdir/f2)
29859         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29860
29861         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29862         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29863
29864         cnt=$(ls -1 $DIR/$tdir | wc -l)
29865         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29866
29867         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29868         createmany -o $DIR/$tdir/f 3
29869         cnt=$(ls -1 $DIR/$tdir | wc -l)
29870         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29871
29872         fid1=$(lfs path2fid $DIR/$tdir/f1)
29873         fid2=$(lfs path2fid $DIR/$tdir/f2)
29874         echo "remove using fsname $FSNAME"
29875         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29876
29877         cnt=$(ls -1 $DIR/$tdir | wc -l)
29878         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29879 }
29880 run_test 421a "simple rm by fid"
29881
29882 test_421b() {
29883         local cnt
29884         local FID1
29885         local FID2
29886
29887         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29888                 skip "Need MDS version at least 2.12.54"
29889
29890         test_mkdir $DIR/$tdir
29891         createmany -o $DIR/$tdir/f 3
29892         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29893         MULTIPID=$!
29894
29895         FID1=$(lfs path2fid $DIR/$tdir/f1)
29896         FID2=$(lfs path2fid $DIR/$tdir/f2)
29897         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29898
29899         kill -USR1 $MULTIPID
29900         wait
29901
29902         cnt=$(ls $DIR/$tdir | wc -l)
29903         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29904 }
29905 run_test 421b "rm by fid on open file"
29906
29907 test_421c() {
29908         local cnt
29909         local FIDS
29910
29911         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29912                 skip "Need MDS version at least 2.12.54"
29913
29914         test_mkdir $DIR/$tdir
29915         createmany -o $DIR/$tdir/f 3
29916         touch $DIR/$tdir/$tfile
29917         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29918         cnt=$(ls -1 $DIR/$tdir | wc -l)
29919         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29920
29921         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29922         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29923
29924         cnt=$(ls $DIR/$tdir | wc -l)
29925         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29926 }
29927 run_test 421c "rm by fid against hardlinked files"
29928
29929 test_421d() {
29930         local cnt
29931         local FIDS
29932
29933         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29934                 skip "Need MDS version at least 2.12.54"
29935
29936         test_mkdir $DIR/$tdir
29937         createmany -o $DIR/$tdir/f 4097
29938         cnt=$(ls -1 $DIR/$tdir | wc -l)
29939         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29940
29941         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29942         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29943
29944         cnt=$(ls $DIR/$tdir | wc -l)
29945         rm -rf $DIR/$tdir
29946         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29947 }
29948 run_test 421d "rmfid en masse"
29949
29950 test_421e() {
29951         local cnt
29952         local FID
29953
29954         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29955         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29956                 skip "Need MDS version at least 2.12.54"
29957
29958         mkdir -p $DIR/$tdir
29959         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29960         createmany -o $DIR/$tdir/striped_dir/f 512
29961         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29962         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29963
29964         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29965                 sed "s/[/][^:]*://g")
29966         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29967
29968         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29969         rm -rf $DIR/$tdir
29970         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29971 }
29972 run_test 421e "rmfid in DNE"
29973
29974 test_421f() {
29975         local cnt
29976         local FID
29977
29978         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29979                 skip "Need MDS version at least 2.12.54"
29980
29981         test_mkdir $DIR/$tdir
29982         touch $DIR/$tdir/f
29983         cnt=$(ls -1 $DIR/$tdir | wc -l)
29984         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29985
29986         FID=$(lfs path2fid $DIR/$tdir/f)
29987         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29988         # rmfid should fail
29989         cnt=$(ls -1 $DIR/$tdir | wc -l)
29990         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29991
29992         chmod a+rw $DIR/$tdir
29993         ls -la $DIR/$tdir
29994         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29995         # rmfid should fail
29996         cnt=$(ls -1 $DIR/$tdir | wc -l)
29997         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29998
29999         rm -f $DIR/$tdir/f
30000         $RUNAS touch $DIR/$tdir/f
30001         FID=$(lfs path2fid $DIR/$tdir/f)
30002         echo "rmfid as root"
30003         $LFS rmfid $DIR $FID || error "rmfid as root failed"
30004         cnt=$(ls -1 $DIR/$tdir | wc -l)
30005         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
30006
30007         rm -f $DIR/$tdir/f
30008         $RUNAS touch $DIR/$tdir/f
30009         cnt=$(ls -1 $DIR/$tdir | wc -l)
30010         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
30011         FID=$(lfs path2fid $DIR/$tdir/f)
30012         # rmfid w/o user_fid2path mount option should fail
30013         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
30014         cnt=$(ls -1 $DIR/$tdir | wc -l)
30015         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
30016
30017         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
30018         stack_trap "rmdir $tmpdir"
30019         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
30020                 error "failed to mount client'"
30021         stack_trap "umount_client $tmpdir"
30022
30023         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
30024         # rmfid should succeed
30025         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
30026         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
30027
30028         # rmfid shouldn't allow to remove files due to dir's permission
30029         chmod a+rwx $tmpdir/$tdir
30030         touch $tmpdir/$tdir/f
30031         ls -la $tmpdir/$tdir
30032         FID=$(lfs path2fid $tmpdir/$tdir/f)
30033         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
30034         return 0
30035 }
30036 run_test 421f "rmfid checks permissions"
30037
30038 test_421g() {
30039         local cnt
30040         local FIDS
30041
30042         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30043         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30044                 skip "Need MDS version at least 2.12.54"
30045
30046         mkdir -p $DIR/$tdir
30047         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30048         createmany -o $DIR/$tdir/striped_dir/f 512
30049         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30050         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30051
30052         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30053                 sed "s/[/][^:]*://g")
30054
30055         rm -f $DIR/$tdir/striped_dir/f1*
30056         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30057         removed=$((512 - cnt))
30058
30059         # few files have been just removed, so we expect
30060         # rmfid to fail on their fids
30061         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30062         [ $removed != $errors ] && error "$errors != $removed"
30063
30064         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30065         rm -rf $DIR/$tdir
30066         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30067 }
30068 run_test 421g "rmfid to return errors properly"
30069
30070 test_421h() {
30071         local mount_other
30072         local mount_ret
30073         local rmfid_ret
30074         local old_fid
30075         local fidA
30076         local fidB
30077         local fidC
30078         local fidD
30079
30080         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30081                 skip "Need MDS version at least 2.15.53"
30082
30083         test_mkdir $DIR/$tdir
30084         test_mkdir $DIR/$tdir/subdir
30085         touch $DIR/$tdir/subdir/file0
30086         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30087         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30088         rm -f $DIR/$tdir/subdir/file0
30089         touch $DIR/$tdir/subdir/fileA
30090         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30091         echo File $DIR/$tdir/subdir/fileA FID $fidA
30092         touch $DIR/$tdir/subdir/fileB
30093         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30094         echo File $DIR/$tdir/subdir/fileB FID $fidB
30095         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30096         touch $DIR/$tdir/subdir/fileC
30097         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30098         echo File $DIR/$tdir/subdir/fileC FID $fidC
30099         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30100         touch $DIR/$tdir/fileD
30101         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30102         echo File $DIR/$tdir/fileD FID $fidD
30103
30104         # mount another client mount point with subdirectory mount
30105         export FILESET=/$tdir/subdir
30106         mount_other=${MOUNT}_other
30107         mount_client $mount_other ${MOUNT_OPTS}
30108         mount_ret=$?
30109         export FILESET=""
30110         (( mount_ret == 0 )) || error "mount $mount_other failed"
30111
30112         echo Removing FIDs:
30113         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30114         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30115         rmfid_ret=$?
30116
30117         umount_client $mount_other || error "umount $mount_other failed"
30118
30119         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30120
30121         # fileA should have been deleted
30122         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30123
30124         # fileB should have been deleted
30125         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30126
30127         # fileC should not have been deleted, fid also exists outside of fileset
30128         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30129
30130         # fileD should not have been deleted, it exists outside of fileset
30131         stat $DIR/$tdir/fileD || error "fileD deleted"
30132 }
30133 run_test 421h "rmfid with fileset mount"
30134
30135 test_422() {
30136         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30137         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30138         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30139         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30140         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30141
30142         local amc=$(at_max_get client)
30143         local amo=$(at_max_get mds1)
30144         local timeout=`lctl get_param -n timeout`
30145
30146         at_max_set 0 client
30147         at_max_set 0 mds1
30148
30149 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30150         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30151                         fail_val=$(((2*timeout + 10)*1000))
30152         touch $DIR/$tdir/d3/file &
30153         sleep 2
30154 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30155         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30156                         fail_val=$((2*timeout + 5))
30157         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30158         local pid=$!
30159         sleep 1
30160         kill -9 $pid
30161         sleep $((2 * timeout))
30162         echo kill $pid
30163         kill -9 $pid
30164         lctl mark touch
30165         touch $DIR/$tdir/d2/file3
30166         touch $DIR/$tdir/d2/file4
30167         touch $DIR/$tdir/d2/file5
30168
30169         wait
30170         at_max_set $amc client
30171         at_max_set $amo mds1
30172
30173         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30174         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30175                 error "Watchdog is always throttled"
30176 }
30177 run_test 422 "kill a process with RPC in progress"
30178
30179 stat_test() {
30180     df -h $MOUNT &
30181     df -h $MOUNT &
30182     df -h $MOUNT &
30183     df -h $MOUNT &
30184     df -h $MOUNT &
30185     df -h $MOUNT &
30186 }
30187
30188 test_423() {
30189     local _stats
30190     # ensure statfs cache is expired
30191     sleep 2;
30192
30193     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30194     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30195
30196     return 0
30197 }
30198 run_test 423 "statfs should return a right data"
30199
30200 test_424() {
30201 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30202         $LCTL set_param fail_loc=0x80000522
30203         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30204         rm -f $DIR/$tfile
30205 }
30206 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30207
30208 test_425() {
30209         test_mkdir -c -1 $DIR/$tdir
30210         $LFS setstripe -c -1 $DIR/$tdir
30211
30212         lru_resize_disable "" 100
30213         stack_trap "lru_resize_enable" EXIT
30214
30215         sleep 5
30216
30217         for i in $(seq $((MDSCOUNT * 125))); do
30218                 local t=$DIR/$tdir/$tfile_$i
30219
30220                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30221                         error_noexit "Create file $t"
30222         done
30223         stack_trap "rm -rf $DIR/$tdir" EXIT
30224
30225         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30226                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30227                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30228
30229                 [ $lock_count -le $lru_size ] ||
30230                         error "osc lock count $lock_count > lru size $lru_size"
30231         done
30232
30233         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30234                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30235                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30236
30237                 [ $lock_count -le $lru_size ] ||
30238                         error "mdc lock count $lock_count > lru size $lru_size"
30239         done
30240 }
30241 run_test 425 "lock count should not exceed lru size"
30242
30243 test_426() {
30244         splice-test -r $DIR/$tfile
30245         splice-test -rd $DIR/$tfile
30246         splice-test $DIR/$tfile
30247         splice-test -d $DIR/$tfile
30248 }
30249 run_test 426 "splice test on Lustre"
30250
30251 test_427() {
30252         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30253         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30254                 skip "Need MDS version at least 2.12.4"
30255         local log
30256
30257         mkdir $DIR/$tdir
30258         mkdir $DIR/$tdir/1
30259         mkdir $DIR/$tdir/2
30260         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30261         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30262
30263         $LFS getdirstripe $DIR/$tdir/1/dir
30264
30265         #first setfattr for creating updatelog
30266         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30267
30268 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30269         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30270         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30271         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30272
30273         sleep 2
30274         fail mds2
30275         wait_recovery_complete mds2 $((2*TIMEOUT))
30276
30277         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30278         echo $log | grep "get update log failed" &&
30279                 error "update log corruption is detected" || true
30280 }
30281 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30282
30283 test_428() {
30284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30285         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30286                               awk '/^max_cached_mb/ { print $2 }')
30287         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30288
30289         $LCTL set_param -n llite.*.max_cached_mb=64
30290
30291         mkdir $DIR/$tdir
30292         $LFS setstripe -c 1 $DIR/$tdir
30293         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30294         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30295         #test write
30296         for f in $(seq 4); do
30297                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30298         done
30299         wait
30300
30301         cancel_lru_locks osc
30302         # Test read
30303         for f in $(seq 4); do
30304                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30305         done
30306         wait
30307 }
30308 run_test 428 "large block size IO should not hang"
30309
30310 test_429() { # LU-7915 / LU-10948
30311         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30312         local testfile=$DIR/$tfile
30313         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30314         local new_flag=1
30315         local first_rpc
30316         local second_rpc
30317         local third_rpc
30318
30319         $LCTL get_param $ll_opencache_threshold_count ||
30320                 skip "client does not have opencache parameter"
30321
30322         set_opencache $new_flag
30323         stack_trap "restore_opencache"
30324         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30325                 error "enable opencache failed"
30326         touch $testfile
30327         # drop MDC DLM locks
30328         cancel_lru_locks mdc
30329         # clear MDC RPC stats counters
30330         $LCTL set_param $mdc_rpcstats=clear
30331
30332         # According to the current implementation, we need to run 3 times
30333         # open & close file to verify if opencache is enabled correctly.
30334         # 1st, RPCs are sent for lookup/open and open handle is released on
30335         #      close finally.
30336         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30337         #      so open handle won't be released thereafter.
30338         # 3rd, No RPC is sent out.
30339         $MULTIOP $testfile oc || error "multiop failed"
30340         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30341         echo "1st: $first_rpc RPCs in flight"
30342
30343         $MULTIOP $testfile oc || error "multiop failed"
30344         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30345         echo "2nd: $second_rpc RPCs in flight"
30346
30347         $MULTIOP $testfile oc || error "multiop failed"
30348         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30349         echo "3rd: $third_rpc RPCs in flight"
30350
30351         #verify no MDC RPC is sent
30352         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30353 }
30354 run_test 429 "verify if opencache flag on client side does work"
30355
30356 lseek_test_430() {
30357         local offset
30358         local file=$1
30359
30360         # data at [200K, 400K)
30361         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30362                 error "256K->512K dd fails"
30363         # data at [2M, 3M)
30364         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30365                 error "2M->3M dd fails"
30366         # data at [4M, 5M)
30367         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30368                 error "4M->5M dd fails"
30369         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30370         # start at first component hole #1
30371         printf "Seeking hole from 1000 ... "
30372         offset=$(lseek_test -l 1000 $file)
30373         echo $offset
30374         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30375         printf "Seeking data from 1000 ... "
30376         offset=$(lseek_test -d 1000 $file)
30377         echo $offset
30378         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30379
30380         # start at first component data block
30381         printf "Seeking hole from 300000 ... "
30382         offset=$(lseek_test -l 300000 $file)
30383         echo $offset
30384         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30385         printf "Seeking data from 300000 ... "
30386         offset=$(lseek_test -d 300000 $file)
30387         echo $offset
30388         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30389
30390         # start at the first component but beyond end of object size
30391         printf "Seeking hole from 1000000 ... "
30392         offset=$(lseek_test -l 1000000 $file)
30393         echo $offset
30394         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30395         printf "Seeking data from 1000000 ... "
30396         offset=$(lseek_test -d 1000000 $file)
30397         echo $offset
30398         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30399
30400         # start at second component stripe 2 (empty file)
30401         printf "Seeking hole from 1500000 ... "
30402         offset=$(lseek_test -l 1500000 $file)
30403         echo $offset
30404         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30405         printf "Seeking data from 1500000 ... "
30406         offset=$(lseek_test -d 1500000 $file)
30407         echo $offset
30408         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30409
30410         # start at second component stripe 1 (all data)
30411         printf "Seeking hole from 3000000 ... "
30412         offset=$(lseek_test -l 3000000 $file)
30413         echo $offset
30414         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30415         printf "Seeking data from 3000000 ... "
30416         offset=$(lseek_test -d 3000000 $file)
30417         echo $offset
30418         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30419
30420         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30421                 error "2nd dd fails"
30422         echo "Add data block at 640K...1280K"
30423
30424         # start at before new data block, in hole
30425         printf "Seeking hole from 600000 ... "
30426         offset=$(lseek_test -l 600000 $file)
30427         echo $offset
30428         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30429         printf "Seeking data from 600000 ... "
30430         offset=$(lseek_test -d 600000 $file)
30431         echo $offset
30432         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30433
30434         # start at the first component new data block
30435         printf "Seeking hole from 1000000 ... "
30436         offset=$(lseek_test -l 1000000 $file)
30437         echo $offset
30438         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30439         printf "Seeking data from 1000000 ... "
30440         offset=$(lseek_test -d 1000000 $file)
30441         echo $offset
30442         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30443
30444         # start at second component stripe 2, new data
30445         printf "Seeking hole from 1200000 ... "
30446         offset=$(lseek_test -l 1200000 $file)
30447         echo $offset
30448         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30449         printf "Seeking data from 1200000 ... "
30450         offset=$(lseek_test -d 1200000 $file)
30451         echo $offset
30452         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30453
30454         # start beyond file end
30455         printf "Using offset > filesize ... "
30456         lseek_test -l 4000000 $file && error "lseek should fail"
30457         printf "Using offset > filesize ... "
30458         lseek_test -d 4000000 $file && error "lseek should fail"
30459
30460         printf "Done\n\n"
30461 }
30462
30463 test_430a() {
30464         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30465                 skip "MDT does not support SEEK_HOLE"
30466
30467         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30468                 skip "OST does not support SEEK_HOLE"
30469
30470         local file=$DIR/$tdir/$tfile
30471
30472         mkdir -p $DIR/$tdir
30473
30474         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30475         # OST stripe #1 will have continuous data at [1M, 3M)
30476         # OST stripe #2 is empty
30477         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30478         lseek_test_430 $file
30479         rm $file
30480         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30481         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30482         lseek_test_430 $file
30483         rm $file
30484         $LFS setstripe -c2 -S 512K $file
30485         echo "Two stripes, stripe size 512K"
30486         lseek_test_430 $file
30487         rm $file
30488         # FLR with stale mirror
30489         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30490                        -N -c2 -S 1M $file
30491         echo "Mirrored file:"
30492         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30493         echo "Plain 2 stripes 1M"
30494         lseek_test_430 $file
30495         rm $file
30496 }
30497 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30498
30499 test_430b() {
30500         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30501                 skip "OST does not support SEEK_HOLE"
30502
30503         local offset
30504         local file=$DIR/$tdir/$tfile
30505
30506         mkdir -p $DIR/$tdir
30507         # Empty layout lseek should fail
30508         $MCREATE $file
30509         # seek from 0
30510         printf "Seeking hole from 0 ... "
30511         lseek_test -l 0 $file && error "lseek should fail"
30512         printf "Seeking data from 0 ... "
30513         lseek_test -d 0 $file && error "lseek should fail"
30514         rm $file
30515
30516         # 1M-hole file
30517         $LFS setstripe -E 1M -c2 -E eof $file
30518         $TRUNCATE $file 1048576
30519         printf "Seeking hole from 1000000 ... "
30520         offset=$(lseek_test -l 1000000 $file)
30521         echo $offset
30522         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30523         printf "Seeking data from 1000000 ... "
30524         lseek_test -d 1000000 $file && error "lseek should fail"
30525         rm $file
30526
30527         # full component followed by non-inited one
30528         $LFS setstripe -E 1M -c2 -E eof $file
30529         dd if=/dev/urandom of=$file bs=1M count=1
30530         printf "Seeking hole from 1000000 ... "
30531         offset=$(lseek_test -l 1000000 $file)
30532         echo $offset
30533         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30534         printf "Seeking hole from 1048576 ... "
30535         lseek_test -l 1048576 $file && error "lseek should fail"
30536         # init second component and truncate back
30537         echo "123" >> $file
30538         $TRUNCATE $file 1048576
30539         printf "Seeking hole from 1000000 ... "
30540         offset=$(lseek_test -l 1000000 $file)
30541         echo $offset
30542         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30543         printf "Seeking hole from 1048576 ... "
30544         lseek_test -l 1048576 $file && error "lseek should fail"
30545         # boundary checks for big values
30546         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30547         offset=$(lseek_test -d 0 $file.10g)
30548         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30549         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30550         offset=$(lseek_test -d 0 $file.100g)
30551         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30552         return 0
30553 }
30554 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30555
30556 test_430c() {
30557         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30558                 skip "OST does not support SEEK_HOLE"
30559
30560         local file=$DIR/$tdir/$tfile
30561         local start
30562
30563         mkdir -p $DIR/$tdir
30564         stack_trap "rm -f $file $file.tmp"
30565         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30566
30567         # cp version 8.33+ prefers lseek over fiemap
30568         local ver=$(cp --version | awk '{ print $4; exit; }')
30569
30570         echo "cp $ver installed"
30571         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30572                 start=$SECONDS
30573                 time cp -v $file $file.tmp || error "cp $file failed"
30574                 (( SECONDS - start < 5 )) || {
30575                         strace cp $file $file.tmp |&
30576                                 grep -E "open|read|seek|FIEMAP" |
30577                                 grep -A 100 $file
30578                         error "cp: too long runtime $((SECONDS - start))"
30579                 }
30580         else
30581                 echo "cp test skipped due to $ver < 8.33"
30582         fi
30583
30584         # tar version 1.29+ supports SEEK_HOLE/DATA
30585         ver=$(tar --version | awk '{ print $4; exit; }')
30586         echo "tar $ver installed"
30587         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30588                 start=$SECONDS
30589                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30590                 (( SECONDS - start < 5 )) || {
30591                         strace tar cf $file.tmp --sparse $file |&
30592                                 grep -E "open|read|seek|FIEMAP" |
30593                                 grep -A 100 $file
30594                         error "tar: too long runtime $((SECONDS - start))"
30595                 }
30596         else
30597                 echo "tar test skipped due to $ver < 1.29"
30598         fi
30599 }
30600 run_test 430c "lseek: external tools check"
30601
30602 test_431() { # LU-14187
30603         local file=$DIR/$tdir/$tfile
30604
30605         mkdir -p $DIR/$tdir
30606         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30607         dd if=/dev/urandom of=$file bs=4k count=1
30608         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30609         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30610         #define OBD_FAIL_OST_RESTART_IO 0x251
30611         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30612         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30613         cp $file $file.0
30614         cancel_lru_locks
30615         sync_all_data
30616         echo 3 > /proc/sys/vm/drop_caches
30617         diff  $file $file.0 || error "data diff"
30618 }
30619 run_test 431 "Restart transaction for IO"
30620
30621 cleanup_test_432() {
30622         do_facet mgs $LCTL nodemap_activate 0
30623         wait_nm_sync active
30624 }
30625
30626 test_432() {
30627         local tmpdir=$TMP/dir432
30628
30629         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30630                 skip "Need MDS version at least 2.14.52"
30631
30632         stack_trap cleanup_test_432 EXIT
30633         mkdir $DIR/$tdir
30634         mkdir $tmpdir
30635
30636         do_facet mgs $LCTL nodemap_activate 1
30637         wait_nm_sync active
30638         do_facet mgs $LCTL nodemap_modify --name default \
30639                 --property admin --value 1
30640         do_facet mgs $LCTL nodemap_modify --name default \
30641                 --property trusted --value 1
30642         cancel_lru_locks mdc
30643         wait_nm_sync default admin_nodemap
30644         wait_nm_sync default trusted_nodemap
30645
30646         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30647                grep -ci "Operation not permitted") -ne 0 ]; then
30648                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30649         fi
30650 }
30651 run_test 432 "mv dir from outside Lustre"
30652
30653 test_433() {
30654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30655
30656         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30657                 skip "inode cache not supported"
30658
30659         $LCTL set_param llite.*.inode_cache=0
30660         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30661
30662         local count=256
30663         local before
30664         local after
30665
30666         cancel_lru_locks mdc
30667         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30668         createmany -m $DIR/$tdir/f $count
30669         createmany -d $DIR/$tdir/d $count
30670         ls -l $DIR/$tdir > /dev/null
30671         stack_trap "rm -rf $DIR/$tdir"
30672
30673         before=$(num_objects)
30674         cancel_lru_locks mdc
30675         after=$(num_objects)
30676
30677         # sometimes even @before is less than 2 * count
30678         while (( before - after < count )); do
30679                 sleep 1
30680                 after=$(num_objects)
30681                 wait=$((wait + 1))
30682                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30683                 if (( wait > 60 )); then
30684                         error "inode slab grew from $before to $after"
30685                 fi
30686         done
30687
30688         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30689 }
30690 run_test 433 "ldlm lock cancel releases dentries and inodes"
30691
30692 test_434() {
30693         local file
30694         local getxattr_count
30695         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30696         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30697
30698         [[ $(getenforce) == "Disabled" ]] ||
30699                 skip "lsm selinux module have to be disabled for this test"
30700
30701         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30702                 error "fail to create $DIR/$tdir/ on MDT0000"
30703
30704         touch $DIR/$tdir/$tfile-{001..100}
30705
30706         # disable the xattr cache
30707         save_lustre_params client "llite.*.xattr_cache" > $p
30708         lctl set_param llite.*.xattr_cache=0
30709         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30710
30711         # clear clients mdc stats
30712         clear_stats $mdc_stat_param ||
30713                 error "fail to clear stats on mdc MDT0000"
30714
30715         for file in $DIR/$tdir/$tfile-{001..100}; do
30716                 getfattr -n security.selinux $file |&
30717                         grep -q "Operation not supported" ||
30718                         error "getxattr on security.selinux should return EOPNOTSUPP"
30719         done
30720
30721         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30722         (( getxattr_count < 100 )) ||
30723                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30724 }
30725 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30726
30727 test_440() {
30728         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30729                 source $LUSTRE/scripts/bash-completion/lustre
30730         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30731                 source /usr/share/bash-completion/completions/lustre
30732         else
30733                 skip "bash completion scripts not found"
30734         fi
30735
30736         local lctl_completions
30737         local lfs_completions
30738
30739         lctl_completions=$(_lustre_cmds lctl)
30740         if [[ ! $lctl_completions =~ "get_param" ]]; then
30741                 error "lctl bash completion failed"
30742         fi
30743
30744         lfs_completions=$(_lustre_cmds lfs)
30745         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30746                 error "lfs bash completion failed"
30747         fi
30748 }
30749 run_test 440 "bash completion for lfs, lctl"
30750
30751 test_442() {
30752         local pid1
30753         local pid2
30754         mkdir -p $DIR/$tdir
30755         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30756         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30757         sleep 1
30758         touch $DIR/$tdir/$tfile.2
30759         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30760         $LCTL set_param fail_loc=0x1430
30761         kill -USR1 $pid1
30762         sleep 1
30763         kill -USR1 $pid2
30764         wait
30765 }
30766 run_test 442 "truncate vs read/write should not panic"
30767
30768 test_460d() {
30769         verify_yaml_available || skip_env "YAML verification not installed"
30770         $LCTL get_param -n sptlrpc.page_pools
30771         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30772                 error "The output of encrypt_page_pools is not an valid YAML"
30773 }
30774 run_test 460d "Check encrypt pools output"
30775
30776 prep_801() {
30777         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30778         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30779                 skip "Need server version at least 2.9.55"
30780
30781         start_full_debug_logging
30782 }
30783
30784 post_801() {
30785         stop_full_debug_logging
30786 }
30787
30788 barrier_stat() {
30789         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30790                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30791                            awk '/The barrier for/ { print $7 }')
30792                 echo $st
30793         else
30794                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30795                 echo \'$st\'
30796         fi
30797 }
30798
30799 barrier_expired() {
30800         local expired
30801
30802         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30803                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30804                           awk '/will be expired/ { print $7 }')
30805         else
30806                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30807         fi
30808
30809         echo $expired
30810 }
30811
30812 test_801a() {
30813         prep_801
30814
30815         echo "Start barrier_freeze at: $(date)"
30816         #define OBD_FAIL_BARRIER_DELAY          0x2202
30817         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30818         # Do not reduce barrier time - See LU-11873
30819         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30820
30821         sleep 2
30822         local b_status=$(barrier_stat)
30823         echo "Got barrier status at: $(date)"
30824         [ "$b_status" = "'freezing_p1'" ] ||
30825                 error "(1) unexpected barrier status $b_status"
30826
30827         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30828         wait
30829         b_status=$(barrier_stat)
30830         [ "$b_status" = "'frozen'" ] ||
30831                 error "(2) unexpected barrier status $b_status"
30832
30833         local expired=$(barrier_expired)
30834         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30835         sleep $((expired + 3))
30836
30837         b_status=$(barrier_stat)
30838         [ "$b_status" = "'expired'" ] ||
30839                 error "(3) unexpected barrier status $b_status"
30840
30841         # Do not reduce barrier time - See LU-11873
30842         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30843                 error "(4) fail to freeze barrier"
30844
30845         b_status=$(barrier_stat)
30846         [ "$b_status" = "'frozen'" ] ||
30847                 error "(5) unexpected barrier status $b_status"
30848
30849         echo "Start barrier_thaw at: $(date)"
30850         #define OBD_FAIL_BARRIER_DELAY          0x2202
30851         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30852         do_facet mgs $LCTL barrier_thaw $FSNAME &
30853
30854         sleep 2
30855         b_status=$(barrier_stat)
30856         echo "Got barrier status at: $(date)"
30857         [ "$b_status" = "'thawing'" ] ||
30858                 error "(6) unexpected barrier status $b_status"
30859
30860         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30861         wait
30862         b_status=$(barrier_stat)
30863         [ "$b_status" = "'thawed'" ] ||
30864                 error "(7) unexpected barrier status $b_status"
30865
30866         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30867         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30868         do_facet mgs $LCTL barrier_freeze $FSNAME
30869
30870         b_status=$(barrier_stat)
30871         [ "$b_status" = "'failed'" ] ||
30872                 error "(8) unexpected barrier status $b_status"
30873
30874         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30875         do_facet mgs $LCTL barrier_thaw $FSNAME
30876
30877         post_801
30878 }
30879 run_test 801a "write barrier user interfaces and stat machine"
30880
30881 test_801b() {
30882         prep_801
30883
30884         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30885         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30886         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30887         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30888         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30889
30890         cancel_lru_locks mdc
30891
30892         # 180 seconds should be long enough
30893         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30894
30895         local b_status=$(barrier_stat)
30896         [ "$b_status" = "'frozen'" ] ||
30897                 error "(6) unexpected barrier status $b_status"
30898
30899         mkdir $DIR/$tdir/d0/d10 &
30900         mkdir_pid=$!
30901
30902         touch $DIR/$tdir/d1/f13 &
30903         touch_pid=$!
30904
30905         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30906         ln_pid=$!
30907
30908         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30909         mv_pid=$!
30910
30911         rm -f $DIR/$tdir/d4/f12 &
30912         rm_pid=$!
30913
30914         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30915
30916         # To guarantee taht the 'stat' is not blocked
30917         b_status=$(barrier_stat)
30918         [ "$b_status" = "'frozen'" ] ||
30919                 error "(8) unexpected barrier status $b_status"
30920
30921         # let above commands to run at background
30922         sleep 5
30923
30924         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30925         ps -p $touch_pid || error "(10) touch should be blocked"
30926         ps -p $ln_pid || error "(11) link should be blocked"
30927         ps -p $mv_pid || error "(12) rename should be blocked"
30928         ps -p $rm_pid || error "(13) unlink should be blocked"
30929
30930         b_status=$(barrier_stat)
30931         [ "$b_status" = "'frozen'" ] ||
30932                 error "(14) unexpected barrier status $b_status"
30933
30934         do_facet mgs $LCTL barrier_thaw $FSNAME
30935         b_status=$(barrier_stat)
30936         [ "$b_status" = "'thawed'" ] ||
30937                 error "(15) unexpected barrier status $b_status"
30938
30939         wait $mkdir_pid || error "(16) mkdir should succeed"
30940         wait $touch_pid || error "(17) touch should succeed"
30941         wait $ln_pid || error "(18) link should succeed"
30942         wait $mv_pid || error "(19) rename should succeed"
30943         wait $rm_pid || error "(20) unlink should succeed"
30944
30945         post_801
30946 }
30947 run_test 801b "modification will be blocked by write barrier"
30948
30949 test_801c() {
30950         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30951
30952         prep_801
30953
30954         stop mds2 || error "(1) Fail to stop mds2"
30955
30956         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30957
30958         local b_status=$(barrier_stat)
30959         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30960                 do_facet mgs $LCTL barrier_thaw $FSNAME
30961                 error "(2) unexpected barrier status $b_status"
30962         }
30963
30964         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30965                 error "(3) Fail to rescan barrier bitmap"
30966
30967         # Do not reduce barrier time - See LU-11873
30968         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30969
30970         b_status=$(barrier_stat)
30971         [ "$b_status" = "'frozen'" ] ||
30972                 error "(4) unexpected barrier status $b_status"
30973
30974         do_facet mgs $LCTL barrier_thaw $FSNAME
30975         b_status=$(barrier_stat)
30976         [ "$b_status" = "'thawed'" ] ||
30977                 error "(5) unexpected barrier status $b_status"
30978
30979         local devname=$(mdsdevname 2)
30980
30981         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30982
30983         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30984                 error "(7) Fail to rescan barrier bitmap"
30985
30986         post_801
30987 }
30988 run_test 801c "rescan barrier bitmap"
30989
30990 test_802b() {
30991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30992         remote_mds_nodsh && skip "remote MDS with nodsh"
30993
30994         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30995                 skip "readonly option not available"
30996
30997         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30998
30999         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
31000                 error "(2) Fail to copy"
31001
31002         # write back all cached data before setting MDT to readonly
31003         cancel_lru_locks
31004         sync_all_data
31005
31006         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
31007         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
31008
31009         echo "Modify should be refused"
31010         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
31011
31012         echo "Read should be allowed"
31013         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
31014                 error "(7) Read should succeed under ro mode"
31015
31016         # disable readonly
31017         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
31018 }
31019 run_test 802b "be able to set MDTs to readonly"
31020
31021 test_803a() {
31022         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31023         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31024                 skip "MDS needs to be newer than 2.10.54"
31025
31026         mkdir_on_mdt0 $DIR/$tdir
31027         # Create some objects on all MDTs to trigger related logs objects
31028         for idx in $(seq $MDSCOUNT); do
31029                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
31030                         $DIR/$tdir/dir${idx} ||
31031                         error "Fail to create $DIR/$tdir/dir${idx}"
31032         done
31033
31034         wait_delete_completed # ensure old test cleanups are finished
31035         sleep 3
31036         echo "before create:"
31037         $LFS df -i $MOUNT
31038         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31039
31040         for i in {1..10}; do
31041                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31042                         error "Fail to create $DIR/$tdir/foo$i"
31043         done
31044
31045         # sync ZFS-on-MDS to refresh statfs data
31046         wait_zfs_commit mds1
31047         sleep 3
31048         echo "after create:"
31049         $LFS df -i $MOUNT
31050         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31051
31052         # allow for an llog to be cleaned up during the test
31053         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31054                 error "before ($before_used) + 10 > after ($after_used)"
31055
31056         for i in {1..10}; do
31057                 rm -rf $DIR/$tdir/foo$i ||
31058                         error "Fail to remove $DIR/$tdir/foo$i"
31059         done
31060
31061         # sync ZFS-on-MDS to refresh statfs data
31062         wait_zfs_commit mds1
31063         wait_delete_completed
31064         sleep 3 # avoid MDT return cached statfs
31065         echo "after unlink:"
31066         $LFS df -i $MOUNT
31067         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31068
31069         # allow for an llog to be created during the test
31070         [ $after_used -le $((before_used + 1)) ] ||
31071                 error "after ($after_used) > before ($before_used) + 1"
31072 }
31073 run_test 803a "verify agent object for remote object"
31074
31075 test_803b() {
31076         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31077         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31078                 skip "MDS needs to be newer than 2.13.56"
31079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31080
31081         for i in $(seq 0 $((MDSCOUNT - 1))); do
31082                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31083         done
31084
31085         local before=0
31086         local after=0
31087
31088         local tmp
31089
31090         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31091         for i in $(seq 0 $((MDSCOUNT - 1))); do
31092                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31093                         awk '/getattr/ { print $2 }')
31094                 before=$((before + tmp))
31095         done
31096         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31097         for i in $(seq 0 $((MDSCOUNT - 1))); do
31098                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31099                         awk '/getattr/ { print $2 }')
31100                 after=$((after + tmp))
31101         done
31102
31103         [ $before -eq $after ] || error "getattr count $before != $after"
31104 }
31105 run_test 803b "remote object can getattr from cache"
31106
31107 test_804() {
31108         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31109         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31110                 skip "MDS needs to be newer than 2.10.54"
31111         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31112
31113         mkdir -p $DIR/$tdir
31114         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31115                 error "Fail to create $DIR/$tdir/dir0"
31116
31117         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31118         local dev=$(mdsdevname 2)
31119
31120         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31121                 grep ${fid} || error "NOT found agent entry for dir0"
31122
31123         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31124                 error "Fail to create $DIR/$tdir/dir1"
31125
31126         touch $DIR/$tdir/dir1/foo0 ||
31127                 error "Fail to create $DIR/$tdir/dir1/foo0"
31128         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31129         local rc=0
31130
31131         for idx in $(seq $MDSCOUNT); do
31132                 dev=$(mdsdevname $idx)
31133                 do_facet mds${idx} \
31134                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31135                         grep ${fid} && rc=$idx
31136         done
31137
31138         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31139                 error "Fail to rename foo0 to foo1"
31140         if [ $rc -eq 0 ]; then
31141                 for idx in $(seq $MDSCOUNT); do
31142                         dev=$(mdsdevname $idx)
31143                         do_facet mds${idx} \
31144                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31145                         grep ${fid} && rc=$idx
31146                 done
31147         fi
31148
31149         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31150                 error "Fail to rename foo1 to foo2"
31151         if [ $rc -eq 0 ]; then
31152                 for idx in $(seq $MDSCOUNT); do
31153                         dev=$(mdsdevname $idx)
31154                         do_facet mds${idx} \
31155                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31156                         grep ${fid} && rc=$idx
31157                 done
31158         fi
31159
31160         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31161
31162         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31163                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31164         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31165                 error "Fail to rename foo2 to foo0"
31166         unlink $DIR/$tdir/dir1/foo0 ||
31167                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31168         rm -rf $DIR/$tdir/dir0 ||
31169                 error "Fail to rm $DIR/$tdir/dir0"
31170
31171         for idx in $(seq $MDSCOUNT); do
31172                 rc=0
31173
31174                 stop mds${idx}
31175                 dev=$(mdsdevname $idx)
31176                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31177                         rc=$?
31178                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31179                         error "mount mds$idx failed"
31180                 df $MOUNT > /dev/null 2>&1
31181
31182                 # e2fsck should not return error
31183                 [ $rc -eq 0 ] ||
31184                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31185         done
31186 }
31187 run_test 804 "verify agent entry for remote entry"
31188
31189 cleanup_805() {
31190         do_facet $SINGLEMDS zfs set quota=$old $fsset
31191         unlinkmany $DIR/$tdir/f- 1000000
31192         trap 0
31193 }
31194
31195 test_805() {
31196         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31197         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31198         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31199                 skip "netfree not implemented before 0.7"
31200         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31201                 skip "Need MDS version at least 2.10.57"
31202
31203         local fsset
31204         local freekb
31205         local usedkb
31206         local old
31207         local quota
31208         local pref="osd-zfs.$FSNAME-MDT0000."
31209
31210         # limit available space on MDS dataset to meet nospace issue
31211         # quickly. then ZFS 0.7.2 can use reserved space if asked
31212         # properly (using netfree flag in osd_declare_destroy()
31213         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31214         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31215                 gawk '{print $3}')
31216         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31217         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31218         let "usedkb=usedkb-freekb"
31219         let "freekb=freekb/2"
31220         if let "freekb > 5000"; then
31221                 let "freekb=5000"
31222         fi
31223         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31224         trap cleanup_805 EXIT
31225         mkdir_on_mdt0 $DIR/$tdir
31226         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31227                 error "Can't set PFL layout"
31228         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31229         rm -rf $DIR/$tdir || error "not able to remove"
31230         do_facet $SINGLEMDS zfs set quota=$old $fsset
31231         trap 0
31232 }
31233 run_test 805 "ZFS can remove from full fs"
31234
31235 # Size-on-MDS test
31236 check_lsom_data()
31237 {
31238         local file=$1
31239         local expect=$(stat -c %s $file)
31240         local msg=$2
31241
31242         check_lsom_size $1 $expect $msg
31243
31244         local blocks=$($LFS getsom -b $file)
31245         expect=$(stat -c %b $file)
31246         [[ $blocks == $expect ]] ||
31247                 error "$msg $file expected blocks: $expect, got: $blocks"
31248 }
31249
31250 check_lsom_size()
31251 {
31252         local size
31253         local expect=$2
31254         local msg=$3
31255
31256         cancel_lru_locks mdc
31257
31258         size=$($LFS getsom -s $1)
31259         [[ $size == $expect ]] ||
31260                 error "$msg $file expected size: $expect, got: $size"
31261 }
31262
31263 test_806() {
31264         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31265                 skip "Need MDS version at least 2.11.52"
31266
31267         local bs=1048576
31268
31269         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31270
31271         disable_opencache
31272         stack_trap "restore_opencache"
31273
31274         # single-threaded write
31275         echo "Test SOM for single-threaded write"
31276         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31277                 error "write $tfile failed"
31278         check_lsom_size $DIR/$tfile $bs "(0)"
31279         # Test SOM with DIO write (dd truncates to 0)
31280         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 oflag=direct ||
31281                 error "write $tfile failed"
31282         check_lsom_size $DIR/$tfile $bs "(1)"
31283
31284         local num=32
31285         local size=$(($num * $bs))
31286         local offset=0
31287         local i
31288
31289         echo "Test SOM for single client multi-threaded($num) write"
31290         $TRUNCATE $DIR/$tfile 0
31291         for ((i = 0; i < $num; i++)); do
31292                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31293                 local pids[$i]=$!
31294                 offset=$((offset + $bs))
31295         done
31296         for (( i=0; i < $num; i++ )); do
31297                 wait ${pids[$i]}
31298         done
31299         check_lsom_size $DIR/$tfile $size "(2)"
31300
31301         $TRUNCATE $DIR/$tfile 0
31302         for ((i = 0; i < $num; i++)); do
31303                 offset=$((offset - $bs))
31304                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31305                 local pids[$i]=$!
31306         done
31307         for (( i=0; i < $num; i++ )); do
31308                 wait ${pids[$i]}
31309         done
31310         check_lsom_size $DIR/$tfile $size "(3)"
31311
31312         # multi-client writes
31313         num=$(get_node_count ${CLIENTS//,/ })
31314         size=$(($num * $bs))
31315         offset=0
31316         i=0
31317
31318         echo "Test SOM for multi-client ($num) writes"
31319         $TRUNCATE $DIR/$tfile 0
31320         for client in ${CLIENTS//,/ }; do
31321                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31322                 local pids[$i]=$!
31323                 i=$((i + 1))
31324                 offset=$((offset + $bs))
31325         done
31326         for (( i=0; i < $num; i++ )); do
31327                 wait ${pids[$i]}
31328         done
31329         check_lsom_size $DIR/$tfile $offset "(4)"
31330
31331         i=0
31332         $TRUNCATE $DIR/$tfile 0
31333         for client in ${CLIENTS//,/ }; do
31334                 offset=$((offset - $bs))
31335                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31336                 local pids[$i]=$!
31337                 i=$((i + 1))
31338         done
31339         for (( i=0; i < $num; i++ )); do
31340                 wait ${pids[$i]}
31341         done
31342         check_lsom_size $DIR/$tfile $size "(5)"
31343
31344         # verify SOM blocks count
31345         echo "Verify SOM block count"
31346         $TRUNCATE $DIR/$tfile 0
31347         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31348                 error "failed to write file $tfile with fdatasync and fstat"
31349         check_lsom_data $DIR/$tfile "(6)"
31350
31351         $TRUNCATE $DIR/$tfile 0
31352         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31353                 error "failed to write file $tfile with fdatasync"
31354         check_lsom_data $DIR/$tfile "(7)"
31355
31356         $TRUNCATE $DIR/$tfile 0
31357         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31358                 error "failed to write file $tfile with sync IO"
31359         check_lsom_data $DIR/$tfile "(8)"
31360
31361         # verify truncate
31362         echo "Test SOM for truncate"
31363         # use ftruncate to sync blocks on close request
31364         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31365         check_lsom_size $DIR/$tfile 16384 "(9)"
31366         check_lsom_data $DIR/$tfile "(10)"
31367
31368         $TRUNCATE $DIR/$tfile 1234
31369         check_lsom_size $DIR/$tfile 1234 "(11)"
31370         # sync blocks on the MDT
31371         $MULTIOP $DIR/$tfile oc
31372         check_lsom_data $DIR/$tfile "(12)"
31373 }
31374 run_test 806 "Verify Lazy Size on MDS"
31375
31376 test_807() {
31377         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31378         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31379                 skip "Need MDS version at least 2.11.52"
31380
31381         # Registration step
31382         changelog_register || error "changelog_register failed"
31383         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31384         changelog_users $SINGLEMDS | grep -q $cl_user ||
31385                 error "User $cl_user not found in changelog_users"
31386
31387         rm -rf $DIR/$tdir || error "rm $tdir failed"
31388         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31389         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31390         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31391         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31392                 error "truncate $tdir/trunc failed"
31393
31394         local bs=1048576
31395         echo "Test SOM for single-threaded write with fsync"
31396         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31397                 error "write $tfile failed"
31398         sync;sync;sync
31399
31400         # multi-client wirtes
31401         local num=$(get_node_count ${CLIENTS//,/ })
31402         local offset=0
31403         local i=0
31404
31405         echo "Test SOM for multi-client ($num) writes"
31406         touch $DIR/$tfile || error "touch $tfile failed"
31407         $TRUNCATE $DIR/$tfile 0
31408         for client in ${CLIENTS//,/ }; do
31409                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31410                 local pids[$i]=$!
31411                 i=$((i + 1))
31412                 offset=$((offset + $bs))
31413         done
31414         for (( i=0; i < $num; i++ )); do
31415                 wait ${pids[$i]}
31416         done
31417
31418         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31419         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31420         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31421         check_lsom_data $DIR/$tdir/trunc "(0)"
31422         check_lsom_data $DIR/$tdir/single_dd "(1)"
31423         check_lsom_data $DIR/$tfile "(2)"
31424
31425         rm -rf $DIR/$tdir
31426         # Deregistration step
31427         changelog_deregister || error "changelog_deregister failed"
31428 }
31429 run_test 807 "verify LSOM syncing tool"
31430
31431 check_som_nologged()
31432 {
31433         local lines=$($LFS changelog $FSNAME-MDT0000 |
31434                 grep 'x=trusted.som' | wc -l)
31435         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31436 }
31437
31438 test_808() {
31439         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31440                 skip "Need MDS version at least 2.11.55"
31441
31442         # Registration step
31443         changelog_register || error "changelog_register failed"
31444
31445         touch $DIR/$tfile || error "touch $tfile failed"
31446         check_som_nologged
31447
31448         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31449                 error "write $tfile failed"
31450         check_som_nologged
31451
31452         $TRUNCATE $DIR/$tfile 1234
31453         check_som_nologged
31454
31455         $TRUNCATE $DIR/$tfile 1048576
31456         check_som_nologged
31457
31458         # Deregistration step
31459         changelog_deregister || error "changelog_deregister failed"
31460 }
31461 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31462
31463 check_som_nodata()
31464 {
31465         $LFS getsom $1
31466         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31467 }
31468
31469 test_809() {
31470         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31471                 skip "Need MDS version at least 2.11.56"
31472
31473         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31474                 error "failed to create DoM-only file $DIR/$tfile"
31475         touch $DIR/$tfile || error "touch $tfile failed"
31476         check_som_nodata $DIR/$tfile
31477
31478         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31479                 error "write $tfile failed"
31480         check_som_nodata $DIR/$tfile
31481
31482         $TRUNCATE $DIR/$tfile 1234
31483         check_som_nodata $DIR/$tfile
31484
31485         $TRUNCATE $DIR/$tfile 4097
31486         check_som_nodata $DIR/$file
31487 }
31488 run_test 809 "Verify no SOM xattr store for DoM-only files"
31489
31490 test_810() {
31491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31492         $GSS && skip_env "could not run with gss"
31493         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31494                 skip "OST < 2.12.58 doesn't align checksum"
31495
31496         set_checksums 1
31497         stack_trap "set_checksums $ORIG_CSUM" EXIT
31498         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31499
31500         local csum
31501         local before
31502         local after
31503         for csum in $CKSUM_TYPES; do
31504                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31505                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31506                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31507                         eval set -- $i
31508                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31509                         before=$(md5sum $DIR/$tfile)
31510                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31511                         after=$(md5sum $DIR/$tfile)
31512                         [ "$before" == "$after" ] ||
31513                                 error "$csum: $before != $after bs=$1 seek=$2"
31514                 done
31515         done
31516 }
31517 run_test 810 "partial page writes on ZFS (LU-11663)"
31518
31519 test_812a() {
31520         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31521                 skip "OST < 2.12.51 doesn't support this fail_loc"
31522         local old
31523
31524         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31525         $LCTL set_param osc.*.idle_timeout=10
31526         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31527
31528         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31529         # ensure ost1 is connected
31530         stat $DIR/$tfile >/dev/null || error "can't stat"
31531         wait_osc_import_state client ost1 FULL
31532         # no locks, no reqs to let the connection idle
31533         cancel_lru_locks osc
31534
31535         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31536 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31537         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31538         wait_osc_import_state client ost1 CONNECTING
31539         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31540
31541         stat $DIR/$tfile >/dev/null || error "can't stat file"
31542 }
31543 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31544
31545 test_812b() { # LU-12378
31546         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31547                 skip "OST < 2.12.51 doesn't support this fail_loc"
31548         local old
31549
31550         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31551         $LCTL set_param osc.*.idle_timeout=10
31552         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31553
31554         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31555         # ensure ost1 is connected
31556         stat $DIR/$tfile >/dev/null || error "can't stat"
31557         wait_osc_import_state client ost1 FULL
31558         # no locks, no reqs to let the connection idle
31559         cancel_lru_locks osc
31560
31561         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31562 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31563         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31564         wait_osc_import_state client ost1 CONNECTING
31565         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31566
31567         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31568         wait_osc_import_state client ost1 IDLE
31569 }
31570 run_test 812b "do not drop no resend request for idle connect"
31571
31572 test_812c() {
31573         local old
31574
31575         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31576
31577         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31578         $LFS getstripe $DIR/$tfile
31579         $LCTL set_param osc.*.idle_timeout=10
31580         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31581         # ensure ost1 is connected
31582         stat $DIR/$tfile >/dev/null || error "can't stat"
31583         wait_osc_import_state client ost1 FULL
31584         # no locks, no reqs to let the connection idle
31585         cancel_lru_locks osc
31586
31587 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31588         $LCTL set_param fail_loc=0x80000533
31589         sleep 15
31590         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31591 }
31592 run_test 812c "idle import vs lock enqueue race"
31593
31594 test_813() {
31595         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31596         [ -z "$file_heat_sav" ] && skip "no file heat support"
31597
31598         local readsample
31599         local writesample
31600         local readbyte
31601         local writebyte
31602         local readsample1
31603         local writesample1
31604         local readbyte1
31605         local writebyte1
31606
31607         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31608         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31609
31610         $LCTL set_param -n llite.*.file_heat=1
31611         echo "Turn on file heat"
31612         echo "Period second: $period_second, Decay percentage: $decay_pct"
31613
31614         echo "QQQQ" > $DIR/$tfile
31615         echo "QQQQ" > $DIR/$tfile
31616         echo "QQQQ" > $DIR/$tfile
31617         cat $DIR/$tfile > /dev/null
31618         cat $DIR/$tfile > /dev/null
31619         cat $DIR/$tfile > /dev/null
31620         cat $DIR/$tfile > /dev/null
31621
31622         local out=$($LFS heat_get $DIR/$tfile)
31623
31624         $LFS heat_get $DIR/$tfile
31625         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31626         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31627         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31628         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31629
31630         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31631         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31632         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31633         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31634
31635         sleep $((period_second + 3))
31636         echo "Sleep $((period_second + 3)) seconds..."
31637         # The recursion formula to calculate the heat of the file f is as
31638         # follow:
31639         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31640         # Where Hi is the heat value in the period between time points i*I and
31641         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31642         # to the weight of Ci.
31643         out=$($LFS heat_get $DIR/$tfile)
31644         $LFS heat_get $DIR/$tfile
31645         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31646         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31647         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31648         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31649
31650         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31651                 error "read sample ($readsample) is wrong"
31652         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31653                 error "write sample ($writesample) is wrong"
31654         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31655                 error "read bytes ($readbyte) is wrong"
31656         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31657                 error "write bytes ($writebyte) is wrong"
31658
31659         echo "QQQQ" > $DIR/$tfile
31660         echo "QQQQ" > $DIR/$tfile
31661         echo "QQQQ" > $DIR/$tfile
31662         cat $DIR/$tfile > /dev/null
31663         cat $DIR/$tfile > /dev/null
31664         cat $DIR/$tfile > /dev/null
31665         cat $DIR/$tfile > /dev/null
31666
31667         sleep $((period_second + 3))
31668         echo "Sleep $((period_second + 3)) seconds..."
31669
31670         out=$($LFS heat_get $DIR/$tfile)
31671         $LFS heat_get $DIR/$tfile
31672         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31673         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31674         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31675         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31676
31677         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31678                 4 * $decay_pct) / 100") -eq 1 ] ||
31679                 error "read sample ($readsample1) is wrong"
31680         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31681                 3 * $decay_pct) / 100") -eq 1 ] ||
31682                 error "write sample ($writesample1) is wrong"
31683         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31684                 20 * $decay_pct) / 100") -eq 1 ] ||
31685                 error "read bytes ($readbyte1) is wrong"
31686         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31687                 15 * $decay_pct) / 100") -eq 1 ] ||
31688                 error "write bytes ($writebyte1) is wrong"
31689
31690         echo "Turn off file heat for the file $DIR/$tfile"
31691         $LFS heat_set -o $DIR/$tfile
31692
31693         echo "QQQQ" > $DIR/$tfile
31694         echo "QQQQ" > $DIR/$tfile
31695         echo "QQQQ" > $DIR/$tfile
31696         cat $DIR/$tfile > /dev/null
31697         cat $DIR/$tfile > /dev/null
31698         cat $DIR/$tfile > /dev/null
31699         cat $DIR/$tfile > /dev/null
31700
31701         out=$($LFS heat_get $DIR/$tfile)
31702         $LFS heat_get $DIR/$tfile
31703         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31704         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31705         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31706         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31707
31708         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31709         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31710         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31711         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31712
31713         echo "Trun on file heat for the file $DIR/$tfile"
31714         $LFS heat_set -O $DIR/$tfile
31715
31716         echo "QQQQ" > $DIR/$tfile
31717         echo "QQQQ" > $DIR/$tfile
31718         echo "QQQQ" > $DIR/$tfile
31719         cat $DIR/$tfile > /dev/null
31720         cat $DIR/$tfile > /dev/null
31721         cat $DIR/$tfile > /dev/null
31722         cat $DIR/$tfile > /dev/null
31723
31724         out=$($LFS heat_get $DIR/$tfile)
31725         $LFS heat_get $DIR/$tfile
31726         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31727         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31728         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31729         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31730
31731         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31732         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31733         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31734         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31735
31736         $LFS heat_set -c $DIR/$tfile
31737         $LCTL set_param -n llite.*.file_heat=0
31738         echo "Turn off file heat support for the Lustre filesystem"
31739
31740         echo "QQQQ" > $DIR/$tfile
31741         echo "QQQQ" > $DIR/$tfile
31742         echo "QQQQ" > $DIR/$tfile
31743         cat $DIR/$tfile > /dev/null
31744         cat $DIR/$tfile > /dev/null
31745         cat $DIR/$tfile > /dev/null
31746         cat $DIR/$tfile > /dev/null
31747
31748         out=$($LFS heat_get $DIR/$tfile)
31749         $LFS heat_get $DIR/$tfile
31750         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31751         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31752         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31753         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31754
31755         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31756         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31757         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31758         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31759
31760         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31761         rm -f $DIR/$tfile
31762 }
31763 run_test 813 "File heat verfication"
31764
31765 test_814()
31766 {
31767         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31768         echo -n y >> $DIR/$tfile
31769         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31770         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31771 }
31772 run_test 814 "sparse cp works as expected (LU-12361)"
31773
31774 test_815()
31775 {
31776         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31777         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31778 }
31779 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31780
31781 test_816() {
31782         local ost1_imp=$(get_osc_import_name client ost1)
31783         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31784                          cut -d'.' -f2)
31785         local old
31786
31787         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31788         $LCTL set_param osc.*.idle_timeout=10
31789         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31790
31791         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31792         # ensure ost1 is connected
31793
31794         stat $DIR/$tfile >/dev/null || error "can't stat"
31795         wait_osc_import_state client ost1 FULL
31796         # no locks, no reqs to let the connection idle
31797         cancel_lru_locks osc
31798         lru_resize_disable osc
31799         local before
31800         local now
31801         before=$($LCTL get_param -n \
31802                  ldlm.namespaces.$imp_name.lru_size)
31803
31804         wait_osc_import_state client ost1 IDLE
31805         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31806         now=$($LCTL get_param -n \
31807               ldlm.namespaces.$imp_name.lru_size)
31808         [ $before == $now ] || error "lru_size changed $before != $now"
31809 }
31810 run_test 816 "do not reset lru_resize on idle reconnect"
31811
31812 cleanup_817() {
31813         umount $tmpdir
31814         exportfs -u localhost:$DIR/nfsexp
31815         rm -rf $DIR/nfsexp
31816 }
31817
31818 test_817() {
31819         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31820
31821         mkdir -p $DIR/nfsexp
31822         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31823                 error "failed to export nfs"
31824
31825         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31826         stack_trap cleanup_817 EXIT
31827
31828         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31829                 error "failed to mount nfs to $tmpdir"
31830
31831         cp /bin/true $tmpdir
31832         $DIR/nfsexp/true || error "failed to execute 'true' command"
31833 }
31834 run_test 817 "nfsd won't cache write lock for exec file"
31835
31836 test_818() {
31837         test_mkdir -i0 -c1 $DIR/$tdir
31838         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31839         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31840         stop $SINGLEMDS
31841
31842         # restore osp-syn threads
31843         stack_trap "fail $SINGLEMDS"
31844
31845         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31846         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31847         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31848                 error "start $SINGLEMDS failed"
31849         rm -rf $DIR/$tdir
31850
31851         local testid=$(echo $TESTNAME | tr '_' ' ')
31852
31853         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31854                 grep "run LFSCK" || error "run LFSCK is not suggested"
31855 }
31856 run_test 818 "unlink with failed llog"
31857
31858 test_819a() {
31859         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31860         cancel_lru_locks osc
31861         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31862         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31863         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31864         rm -f $TDIR/$tfile
31865 }
31866 run_test 819a "too big niobuf in read"
31867
31868 test_819b() {
31869         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31870         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31871         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31872         cancel_lru_locks osc
31873         sleep 1
31874         rm -f $TDIR/$tfile
31875 }
31876 run_test 819b "too big niobuf in write"
31877
31878
31879 function test_820_start_ost() {
31880         sleep 5
31881
31882         for num in $(seq $OSTCOUNT); do
31883                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31884         done
31885 }
31886
31887 test_820() {
31888         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31889
31890         mkdir $DIR/$tdir
31891         umount_client $MOUNT || error "umount failed"
31892         for num in $(seq $OSTCOUNT); do
31893                 stop ost$num
31894         done
31895
31896         # mount client with no active OSTs
31897         # so that the client can't initialize max LOV EA size
31898         # from OSC notifications
31899         mount_client $MOUNT || error "mount failed"
31900         # delay OST starting to keep this 0 max EA size for a while
31901         test_820_start_ost &
31902
31903         # create a directory on MDS2
31904         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31905                 error "Failed to create directory"
31906         # open intent should update default EA size
31907         # see mdc_update_max_ea_from_body()
31908         # notice this is the very first RPC to MDS2
31909         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31910         ret=$?
31911         echo $out
31912         # With SSK, this situation can lead to -EPERM being returned.
31913         # In that case, simply retry.
31914         if [ $ret -ne 0 ] && $SHARED_KEY; then
31915                 if echo "$out" | grep -q "not permitted"; then
31916                         cp /etc/services $DIR/$tdir/mds2
31917                         ret=$?
31918                 fi
31919         fi
31920         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31921 }
31922 run_test 820 "update max EA from open intent"
31923
31924 test_823() {
31925         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31926         local OST_MAX_PRECREATE=20000
31927
31928         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31929                 skip "Need MDS version at least 2.14.56"
31930
31931         save_lustre_params mds1 \
31932                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31933         do_facet $SINGLEMDS "$LCTL set_param -n \
31934                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31935         do_facet $SINGLEMDS "$LCTL set_param -n \
31936                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31937
31938         stack_trap "restore_lustre_params < $p; rm $p"
31939
31940         do_facet $SINGLEMDS "$LCTL set_param -n \
31941                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31942
31943         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31944                       osp.$FSNAME-OST0000*MDT0000.create_count")
31945         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31946                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31947         local expect_count=$(((($max/2)/256) * 256))
31948
31949         log "setting create_count to 100200:"
31950         log " -result- count: $count with max: $max, expecting: $expect_count"
31951
31952         [[ $count -eq expect_count ]] ||
31953                 error "Create count not set to max precreate."
31954 }
31955 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31956
31957 test_831() {
31958         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31959                 skip "Need MDS version 2.14.56"
31960
31961         local sync_changes=$(do_facet $SINGLEMDS \
31962                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31963
31964         [ "$sync_changes" -gt 100 ] &&
31965                 skip "Sync changes $sync_changes > 100 already"
31966
31967         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31968
31969         $LFS mkdir -i 0 $DIR/$tdir
31970         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31971
31972         save_lustre_params mds1 \
31973                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31974         save_lustre_params mds1 \
31975                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31976
31977         do_facet mds1 "$LCTL set_param -n \
31978                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31979                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31980         stack_trap "restore_lustre_params < $p" EXIT
31981
31982         createmany -o $DIR/$tdir/f- 1000
31983         unlinkmany $DIR/$tdir/f- 1000 &
31984         local UNLINK_PID=$!
31985
31986         while sleep 1; do
31987                 sync_changes=$(do_facet mds1 \
31988                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31989                 # the check in the code is racy, fail the test
31990                 # if the value above the limit by 10.
31991                 [ $sync_changes -gt 110 ] && {
31992                         kill -2 $UNLINK_PID
31993                         wait
31994                         error "osp changes throttling failed, $sync_changes>110"
31995                 }
31996                 kill -0 $UNLINK_PID 2> /dev/null || break
31997         done
31998         wait
31999 }
32000 run_test 831 "throttling unlink/setattr queuing on OSP"
32001
32002 test_832() {
32003         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
32004         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
32005                 skip "Need MDS version 2.15.52+"
32006         is_rmentry_supported || skip "rm_entry not supported"
32007
32008         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
32009         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
32010         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
32011                 error "mkdir remote_dir failed"
32012         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
32013                 error "mkdir striped_dir failed"
32014         touch $DIR/$tdir/file || error "touch file failed"
32015         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
32016         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
32017 }
32018 run_test 832 "lfs rm_entry"
32019
32020 test_833() {
32021         local file=$DIR/$tfile
32022
32023         stack_trap "rm -f $file" EXIT
32024         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
32025
32026         local wpid
32027         local rpid
32028         local rpid2
32029
32030         # Buffered I/O write
32031         (
32032                 while [ ! -e $DIR/sanity.833.lck ]; do
32033                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
32034                                 error "failed to write $file"
32035                         sleep 0.$((RANDOM % 4 + 1))
32036                 done
32037         )&
32038         wpid=$!
32039
32040         # Buffered I/O read
32041         (
32042                 while [ ! -e $DIR/sanity.833.lck ]; do
32043                         dd if=$file of=/dev/null bs=1M count=50 ||
32044                                 error "failed to read $file"
32045                         sleep 0.$((RANDOM % 4 + 1))
32046                 done
32047         )&
32048         rpid=$!
32049
32050         # Direct I/O read
32051         (
32052                 while [ ! -e $DIR/sanity.833.lck ]; do
32053                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32054                                 error "failed to read $file in direct I/O mode"
32055                         sleep 0.$((RANDOM % 4 + 1))
32056                 done
32057         )&
32058         rpid2=$!
32059
32060         sleep 30
32061         touch $DIR/sanity.833.lck
32062         wait $wpid || error "$?: buffered write failed"
32063         wait $rpid || error "$?: buffered read failed"
32064         wait $rpid2 || error "$?: direct read failed"
32065 }
32066 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32067
32068 test_842() {
32069         local oss1=$(facet_host ost1)
32070
32071         # Try to insert the module.  This will leave results in dmesg
32072         now=$(date +%s)
32073         log "STAMP $now" > /dev/kmsg
32074         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32075                 error "$oss1 load_module ldlm_extent failed"
32076
32077         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32078         do_node $oss1 rmmod -v ldlm_extent ||
32079                 error "rmmod failed (may trigger a failure in a later test)"
32080 }
32081 run_test 842 "Measure ldlm_extent performance"
32082
32083 test_850() {
32084         local dir=$DIR/$tdir
32085         local file=$dir/$tfile
32086         local statsfile=$dir/all_job_stats.txt
32087
32088         test_mkdir -p $dir || error "failed to create dir $dir"
32089         echo "abcdefg" > $file || error "failed to create file $file"
32090
32091         # read job_stats in the living system
32092         lljobstat -n 1 ||
32093                 error "failed to run lljobstat on living system"
32094
32095         $LCTL get_param *.*.job_stats > $statsfile
32096         lljobstat --statsfile=$statsfile ||
32097                 error "failed to run lljobstat on file $statsfile"
32098 }
32099 run_test 850 "lljobstat can parse living and aggregated job_stats"
32100
32101 test_851() {
32102         local dir=$DIR/$tdir
32103         local file=$dir/f_test_851_$$
32104         local report=/tmp/report_test_851_$$
32105         local fanotify_prog=monitor_lustrefs
32106         local pid
32107
32108         test_mkdir $dir || error "failed to create dir $dir"
32109
32110         $fanotify_prog $DIR > $report &
32111         pid=$!
32112
32113         sleep 1
32114         if ! kill -0 $pid; then
32115                 error "failed to start $fanoify_prog"
32116         fi
32117
32118         stack_trap "kill $pid"
32119         stack_trap "rm -f $report"
32120
32121         echo "1234567890" > $file
32122         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32123                 error "fanotify did not report anything after 30 seconds"
32124         grep -a -E "open.*:$file:" $report ||
32125                 error "no open event for writing $file"
32126         grep -a -E "write.*:$file:" $report ||
32127                 error "no write event for writing $file"
32128         grep -a -E "close.*:$file:" $report ||
32129                 error "no close event for writing $file"
32130
32131         > $report
32132         cat $file
32133         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32134                 error "fanotify did not report anything after 30 seconds"
32135         grep -a -E "open.*:$file:" $report ||
32136                 error "no open event for reading $file"
32137         grep -a -E "read.*:$file:" $report ||
32138                 error "no write event for reading $file"
32139         grep -a -E "close.*:$file:" $report ||
32140                 error "no close event for reading $file"
32141 }
32142 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32143
32144 #
32145 # tests that do cleanup/setup should be run at the end
32146 #
32147
32148 test_900() {
32149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32150         local ls
32151
32152         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32153         $LCTL set_param fail_loc=0x903
32154
32155         cancel_lru_locks MGC
32156
32157         FAIL_ON_ERROR=true cleanup
32158         FAIL_ON_ERROR=true setup
32159 }
32160 run_test 900 "umount should not race with any mgc requeue thread"
32161
32162 # LUS-6253/LU-11185
32163 test_901() {
32164         local old
32165         local count
32166         local oldc
32167         local newc
32168         local olds
32169         local news
32170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32171
32172         # some get_param have a bug to handle dot in param name
32173         cancel_lru_locks MGC
32174         old=$(mount -t lustre | wc -l)
32175         # 1 config+sptlrpc
32176         # 2 params
32177         # 3 nodemap
32178         # 4 IR
32179         old=$((old * 4))
32180         oldc=0
32181         count=0
32182         while [ $old -ne $oldc ]; do
32183                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32184                 sleep 1
32185                 ((count++))
32186                 if [ $count -ge $TIMEOUT ]; then
32187                         error "too large timeout"
32188                 fi
32189         done
32190         umount_client $MOUNT || error "umount failed"
32191         mount_client $MOUNT || error "mount failed"
32192         cancel_lru_locks MGC
32193         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32194
32195         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32196
32197         return 0
32198 }
32199 run_test 901 "don't leak a mgc lock on client umount"
32200
32201 # LU-13377
32202 test_902() {
32203         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32204                 skip "client does not have LU-13377 fix"
32205         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32206         $LCTL set_param fail_loc=0x1415
32207         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32208         cancel_lru_locks osc
32209         rm -f $DIR/$tfile
32210 }
32211 run_test 902 "test short write doesn't hang lustre"
32212
32213 # LU-14711
32214 test_903() {
32215         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32216         echo "blah" > $DIR/${tfile}-2
32217         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32218         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32219         $LCTL set_param fail_loc=0x417 fail_val=20
32220
32221         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32222         sleep 1 # To start the destroy
32223         wait_destroy_complete 150 || error "Destroy taking too long"
32224         cat $DIR/$tfile > /dev/null || error "Evicted"
32225 }
32226 run_test 903 "Test long page discard does not cause evictions"
32227
32228 test_904() {
32229         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32230         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32231                 grep -q project || skip "skip project quota not supported"
32232
32233         local testfile="$DIR/$tdir/$tfile"
32234         local xattr="trusted.projid"
32235         local projid
32236         local mdts=$(comma_list $(mdts_nodes))
32237         local saved=$(do_facet mds1 $LCTL get_param -n \
32238                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32239
32240         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32241         stack_trap "do_nodes $mdts $LCTL set_param \
32242                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32243
32244         mkdir -p $DIR/$tdir
32245         touch $testfile
32246         #hide projid xattr on server
32247         $LFS project -p 1 $testfile ||
32248                 error "set $testfile project id failed"
32249         getfattr -m - $testfile | grep $xattr &&
32250                 error "do not show trusted.projid when disabled on server"
32251         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32252         #should be hidden when projid is 0
32253         $LFS project -p 0 $testfile ||
32254                 error "set $testfile project id failed"
32255         getfattr -m - $testfile | grep $xattr &&
32256                 error "do not show trusted.projid with project ID 0"
32257
32258         #still can getxattr explicitly
32259         projid=$(getfattr -n $xattr $testfile |
32260                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32261         [ $projid == "0" ] ||
32262                 error "projid expected 0 not $projid"
32263
32264         #set the projid via setxattr
32265         setfattr -n $xattr -v "1000" $testfile ||
32266                 error "setattr failed with $?"
32267         projid=($($LFS project $testfile))
32268         [ ${projid[0]} == "1000" ] ||
32269                 error "projid expected 1000 not $projid"
32270
32271         #check the new projid via getxattr
32272         $LFS project -p 1001 $testfile ||
32273                 error "set $testfile project id failed"
32274         getfattr -m - $testfile | grep $xattr ||
32275                 error "should show trusted.projid when project ID != 0"
32276         projid=$(getfattr -n $xattr $testfile |
32277                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32278         [ $projid == "1001" ] ||
32279                 error "projid expected 1001 not $projid"
32280
32281         #try to set invalid projid
32282         setfattr -n $xattr -v "4294967295" $testfile &&
32283                 error "set invalid projid should fail"
32284
32285         #remove the xattr means setting projid to 0
32286         setfattr -x $xattr $testfile ||
32287                 error "setfattr failed with $?"
32288         projid=($($LFS project $testfile))
32289         [ ${projid[0]} == "0" ] ||
32290                 error "projid expected 0 not $projid"
32291
32292         #should be hidden when parent has inherit flag and same projid
32293         $LFS project -srp 1002 $DIR/$tdir ||
32294                 error "set $tdir project id failed"
32295         getfattr -m - $testfile | grep $xattr &&
32296                 error "do not show trusted.projid with inherit flag"
32297
32298         #still can getxattr explicitly
32299         projid=$(getfattr -n $xattr $testfile |
32300                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32301         [ $projid == "1002" ] ||
32302                 error "projid expected 1002 not $projid"
32303 }
32304 run_test 904 "virtual project ID xattr"
32305
32306 # LU-8582
32307 test_905() {
32308         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32309                 skip "need OST version >= 2.15.50.220 for fail_loc"
32310
32311         remote_ost_nodsh && skip "remote OST with nodsh"
32312         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32313
32314         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32315
32316         #define OBD_FAIL_OST_OPCODE 0x253
32317         # OST_LADVISE = 21
32318         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32319         $LFS ladvise -a willread $DIR/$tfile &&
32320                 error "unexpected success of ladvise with fault injection"
32321         $LFS ladvise -a willread $DIR/$tfile |&
32322                 grep -q "Operation not supported"
32323         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32324 }
32325 run_test 905 "bad or new opcode should not stuck client"
32326
32327 test_906() {
32328         grep -q io_uring_setup /proc/kallsyms ||
32329                 skip "Client OS does not support io_uring I/O engine"
32330         io_uring_probe || skip "kernel does not support io_uring fully"
32331         which fio || skip_env "no fio installed"
32332         fio --enghelp | grep -q io_uring ||
32333                 skip_env "fio does not support io_uring I/O engine"
32334
32335         local file=$DIR/$tfile
32336         local ioengine="io_uring"
32337         local numjobs=2
32338         local size=50M
32339
32340         fio --name=seqwrite --ioengine=$ioengine        \
32341                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32342                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32343                 error "fio seqwrite $file failed"
32344
32345         fio --name=seqread --ioengine=$ioengine \
32346                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32347                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32348                 error "fio seqread $file failed"
32349
32350         rm -f $file || error "rm -f $file failed"
32351 }
32352 run_test 906 "Simple test for io_uring I/O engine via fio"
32353
32354 test_907() {
32355         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32356
32357         # set stripe size to max rpc size
32358         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32359         $LFS getstripe $DIR/$tfile
32360 #define OBD_FAIL_OST_EROFS               0x216
32361         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32362
32363         local bs=$((max_pages * PAGE_SIZE / 16))
32364
32365         # write full one stripe and one block
32366         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32367
32368         rm $DIR/$tfile || error "rm failed"
32369 }
32370 run_test 907 "write rpc error during unlink"
32371
32372 complete_test $SECONDS
32373 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32374 check_and_cleanup_lustre
32375 if [ "$I_MOUNTED" != "yes" ]; then
32376         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32377 fi
32378 exit_status